为什么GROUPBY with LEFT JOIN会更改此MySQL查询的结果?
为了保护客户机信息的隐私,我将表名和字段名重写为通用名,并将问题减少到最小表达式。这意味着这里的为什么GROUPBY with LEFT JOIN会更改此MySQL查询的结果?,mysql,Mysql,为了保护客户机信息的隐私,我将表名和字段名重写为通用名,并将问题减少到最小表达式。这意味着这里的GROUP BY可能没有意义,但它在更大的范围内有意义(因为原始查询有更多选择的值) 数据: 为什么这两个查询返回带有[*]标记的行的不同值 A)无分组依据 SELECT COUNT(table1.id) AS cnt1, COUNT(table2.id) AS cnt2, (SELECT COUNT(table2_copy.id) FROM table2 table2_copy
GROUP BY
可能没有意义,但它在更大的范围内有意义(因为原始查询有更多选择的值)
数据:
为什么这两个查询返回带有[*]标记的行的不同值
A)无分组依据
SELECT COUNT(table1.id) AS cnt1, COUNT(table2.id) AS cnt2,
(SELECT COUNT(table2_copy.id) FROM table2 table2_copy
WHERE table2_copy.some_id_1 = table2.id
) AS cnt3,
(SELECT COUNT(table2_copy.id) FROM table2 table2_copy
LEFT JOIN table3 ON table2_copy.some_id_2 = table3.id /*[*]*/
WHERE table2_copy.some_id_1 = table2.id
) AS cnt4
FROM table1
INNER JOIN table2 ON (table1.id = table2.id)
WHERE table1.id = 100
SELECT COUNT(table1.id) AS cnt1, COUNT(table2.id) AS cnt2,
(SELECT COUNT(table2_copy.id) FROM table2 table2_copy
WHERE table2_copy.some_id_1 = table2.id
) AS cnt3,
(SELECT COUNT(table2_copy.id) FROM table2 table2_copy
LEFT JOIN table3 ON table2_copy.some_id_2 = table3.id /*[*]*/
WHERE table2_copy.some_id_1 = table2.id
) AS cnt4
FROM table1
INNER JOIN table2 ON (table1.id = table2.id)
WHERE table1.id = 100 GROUP BY table1.id /* <-- THE ONLY DIFFERENCE */
返回:
array(1) {
[0]=>
array(4) {
["cnt1"]=>
string(1) "1"
["cnt2"]=>
string(1) "1"
["cnt3"]=>
string(1) "2"
["cnt4"]=>
string(1) "2" // Differs from cnt3 query only because of the [*] line
}
}
array(1) {
[0]=>
array(4) {
["cnt1"]=>
string(1) "1"
["cnt2"]=>
string(1) "1"
["cnt3"]=>
string(1) "2"
["cnt4"]=>
string(1) "0" // <-- DIFFERENT
}
}
B)与
分组依据
SELECT COUNT(table1.id) AS cnt1, COUNT(table2.id) AS cnt2,
(SELECT COUNT(table2_copy.id) FROM table2 table2_copy
WHERE table2_copy.some_id_1 = table2.id
) AS cnt3,
(SELECT COUNT(table2_copy.id) FROM table2 table2_copy
LEFT JOIN table3 ON table2_copy.some_id_2 = table3.id /*[*]*/
WHERE table2_copy.some_id_1 = table2.id
) AS cnt4
FROM table1
INNER JOIN table2 ON (table1.id = table2.id)
WHERE table1.id = 100
SELECT COUNT(table1.id) AS cnt1, COUNT(table2.id) AS cnt2,
(SELECT COUNT(table2_copy.id) FROM table2 table2_copy
WHERE table2_copy.some_id_1 = table2.id
) AS cnt3,
(SELECT COUNT(table2_copy.id) FROM table2 table2_copy
LEFT JOIN table3 ON table2_copy.some_id_2 = table3.id /*[*]*/
WHERE table2_copy.some_id_1 = table2.id
) AS cnt4
FROM table1
INNER JOIN table2 ON (table1.id = table2.id)
WHERE table1.id = 100 GROUP BY table1.id /* <-- THE ONLY DIFFERENCE */
它的工作原理与我预期的一样:cnt4
是2
此外,这些查询(无表2): 以及: 返回两个:
array(1) {
[0]=>
array(3) {
["cnt1"]=>
string(1) "1"
["cnt3"]=>
string(1) "2"
["cnt4"]=>
string(1) "2"
}
}
所以问题似乎是这三条线的结合:
SELECT (SELECT ...
LEFT JOIN ... /* THIS LINE */
...) FROM ...
INNER JOIN ... /* THIS LINE */
WHERE ...
GROUP BY ... /* AND THIS LINE */
谢谢。注意:仅适用于MySQL
分组依据
是按顺序返回结果,不同
不是
groupby
以及orderby NULL
与DISTINCT
具有相同的效率(并以say方式实现)。如果要聚合(或区分)的字段上有索引,则这两个子句都会在此字段上使用松散索引扫描
在“分组依据”中,可以返回未分组和未聚合的表达式MySQL
将从相应的组中选取任意随机值来计算表达式
使用
groupby
,可以从SELECT
子句中省略groupby
表达式。使用DISTINCT
,您不能。DISTINCT
返回的每一行都保证是唯一的。您如何应用这些信息来回答这个问题?以不同的方式分组,使用聚合和不使用聚合。由于我没有任何表数据,我无法给出确切的信息,说明为什么在使用group by时第三行得到2。好的,我会尝试将数据添加到问题中。我需要更多信息来确定,但我确信这是因为group by不包括所有选定的列。Mysql只是在本例中有多行可用时选择行。谢谢Sebas。是的,但是如果只有一行可供选择怎么办?情况就是这样(在WHERE
条件中检查),所以我不明白发生了什么。顺便说一句,我不知道你什么时候开始阅读这个问题,但是数据是在一开始上传的。我很好奇一件事。请在WHERE子句中添加和table2.id=100
,如果有,请告诉我change@Sebas没有变化:cnt4仍然是0:/我不明白的是,如果我从一开始就创建了all(在一个新数据库中),它工作得很好:cnt4始终是2,但在我的数据库里它不是。。。
array(1) {
[0]=>
array(3) {
["cnt1"]=>
string(1) "1"
["cnt3"]=>
string(1) "2"
["cnt4"]=>
string(1) "2"
}
}
SELECT (SELECT ...
LEFT JOIN ... /* THIS LINE */
...) FROM ...
INNER JOIN ... /* THIS LINE */
WHERE ...
GROUP BY ... /* AND THIS LINE */