使用GROUP_CONCAT()
通常会调用分组逻辑并创建临时表,这通常会对性能产生很大的负面影响。有时,您可以添加正确的索引来避免按组查询中的临时表,但并非在每种情况下都如此。
https://stackoverflow.com/a/26225148/9685125
阅读这篇文章后,我意识到自己做错了,因为很多时候我都使用巨大的GROUP_CONCAT()
进行复杂的查询。如
GROUP_CONCAT(DISTINCT exam.title) AS exam,
GROUP_CONCAT(subject.title, '<br/> Th - ', mark.th, ' | PR - ', mark.pr SEPARATOR ',') AS mark
但是在以下情况下,不用GROUP_CONCAT
可以替代subquery
。我的意思是只使用Mysql join
例如,让我们看两个关系数据库,然后查询以解释我的问题
学生
id | Rid | name
========================
1 | 1 | john
标记
id | std_id | th
======================
1 | 1 | 60
2 | 1 | 70
3 | 1 | 80
4 | 1 | 90
"SELECT
student.en_name, mark.th
FROM student
JOIN mark ON student.id = mark.std_id
WHERE student.id=:id;"
如果仅使用JOIN
John: 60, John: 70, John: 80, John: 90
因此,我使用GROUP BY
。但是,如果我将GROUP BY
分配给student.id,则只会获取第一行
"SELECT
student.en_name, mark.th
FROM student
JOIN mark ON student.id = mark.std_id
WHERE student.id=:id
GROUP BY student.id;"
Result is
John: 60
要获得结果,我们必须分配group.concat
"SELECT
student.en_name,
GROUP_CONCAT(mark.th) as mark
FROM student
JOIN mark ON student.id = mark.std_id
WHERE student.id=:id
GROUP BY student.id;"
使用爆炸数组的最终结果和预期结果
$name=$row['en_name'];
echo "$name: <br/>";
$mrk_array = explode(',',$row['mark']);
foreach($mrk_array as $mark){
echo $mark.", ";
}
John:
60, 70, 80, 90,
在这里,我看不到GROUP_CONCAT
的任何替代方法来获取每个Id
的所有关联值并防止重复,请从这里帮助我如何替换GROUP_CONCAT
。
还有,一个朋友告诉我
所以,如果要“爆炸”它,为什么要GROUP_CONCAT
。您最好返回一个不错的关联数组,然后在此处显示它。
但是我不明白,他是什么意思?
答案 0 :(得分:2)
评论太久了...
使用原始查询,您将有效地返回一个行数组(关联数组):
array(array('en_name' => 'John', 'mark' => 60),
array('en_name' => 'John', 'mark' => 70),
array('en_name' => 'John', 'mark' => 80),
array('en_name' => 'John', 'mark' => 90)
)
使用GROUP BY
和GROUP CONCAT
时,实际上就是该数组的imploding
元素'mark'
到
array('en_name => 'John', 'mark' => '60,70,80,90')
然后必须再次explode
数组以处理数据。
如果您坚持使用原始查询,则可以在应用程序框架中进行内插,例如
$name = "";
while ($row = $result->fetch()) {
if ($row['en_name'] != $name) {
$name = $row['en_name'];
echo "$name: <br/>" . $row['mark'];
}
else {
echo ',' . $row['mark'];
}
}
输出:
John:
60,70,80,90
这通常比在数据库中使用GROUP BY
和GROUP_CONCAT
要快得多。