1

我花了很长时间试图自己想出一个解决这个问题的好方法。还没有找到任何好的答案来提供帮助,尽管我尝试过从不同的答案中划分解决方案,但没有运气。

目标:展示一个分页的项目页面,其中包含来自多个表的数据。

我在单个 MYSQL 查询中使用了多个连接,因为我想避免在 PHP 循环中运行查询。while(fetch_assoc)仅此一项就引入了 fetch_assoc 问题,由于查询产生的重复行,我不得不从循环中构建自己的结果数组。然而,下一个问题是查询通过一个分页类运行,我用它来生成分页链接并获取查询数据,如 num_rows 等。

所以现在,我有一个页面显示我想要的数据,但是分页类向我显示了错误的行数和分页链接。不确定解决此问题的最佳方法是什么。希望从你们中的一位出色的专家那里得到一些想法!

代码基本上是:

$sql = "...."

$projects = new pager($sql)

echo $projects->num_rows

while($projects->fetch_assoc){
build new array from data
$project_array[][][]
}

foreach($project_array){
display data from all tables...
}

$projects->showPageLinks

SQLFiddle提供了我获得的数据的示例:

请注意,有 7 个结果行,但只有 4 个项目。所以分页类显示 7 个 num_rows (正确),但只有 4 个项目。

欢迎任何想法!

我虽然可能将来自其他表的子查询结果连接到自己的列中的字符串值,并使用 phpexplode()等解析它,然后生成包含所有数据的单个项目行,但我还没有能够做到这一点。

预先感谢您的帮助!

4

1 回答 1

0

我能想出的唯一解决方案是将子查询/连接的结果连接到主结果集中的单个列中。这使我无需修改分页类即可获得所需的结果。

请参阅此SQLFiddle中的串联结果示例

示例查询:

SELECT p.id pid, p.name pname, c.name cname,
GROUP_CONCAT(DISTINCT CONCAT_WS('|',w.hours,w.notes,t.name) SEPARATOR ';') as works

FROM projects p
LEFT JOIN (SELECT * FROM clients) AS c ON c.id=p.client_id
LEFT JOIN (SELECT * FROM work) AS w ON w.project_id=p.id
LEFT JOIN (SELECT * FROM tools) AS t ON t.id=w.tool_id
GROUP BY p.id

GROUP_CONCAT(DISTINCT ...是连接连接结果中的各个行,以及CONCAT_WS('',col,col,..)连接各个结果列的内容。两者都允许您使用您定义的分隔符,就像 phpimplode()一样。最终,您最终会在单个列/行中得到一个格式化的结果字符串,您可以在其中使用 php 到explode()行,然后是它们的列。

现在我得到了正确的结果计数,并通过定义的分隔符简单地分解行和字段。

示例代码:

$wkeys = array('hours','notes','toolname'); // to use as array key (column name)

while($r=$projects->fetch_assoc()){
    if(strpos($r['works'],';')!==false){
        $wrows = explode(";",$r['works']); // individual rows

        foreach($wrows as $k=>$v) { 
            $wv = explode("|",$v); // individual col=val pairs
            $works[] = array_combine($wkeys,$wv); 
        }
    }
}

希望这可以帮助其他可能面临同样情况的人。

编辑:虽然这个解决方案对我来说效果很好,但我最终遇到了默认长度限制为GROUP_CONCAT1024 的问题。任何超过 1024 的值都被减少到 1024。请参阅这个答案来解决这个问题。我建议您积极主动并立即更改它,除非您绝对确定您的值永远不会超过 1024。

于 2015-02-23T23:55:30.853 回答