选择 SELECT 中的多个列时,使用 GROUP BY 和 ORDER BY 的查询不起作用

Query with GROUP BY and ORDER BY not working when multiple columns in SELECT are chosen

我正在更新旧网站,其中一个查询不再有效:

SELECT * FROM tbl WHERE col1 IS NULL GROUP BY col2 ORDER BY col2

我注意到如果我删除 GROUP BY 它会起作用,但结果集与原始结果集不匹配:

SELECT * FROM tbl WHERE col1 IS NULL ORDER BY col2

所以我尝试阅读 docs 中的 GROUP BY 以查看可能是什么问题,它似乎建议不要使用 * 到 select字段,但明确使用列名,所以我只使用正在排序和分组的列进行了尝试:

SELECT col2 FROM tbl WHERE col1 IS NULL GROUP BY col2 ORDER BY col2

这行得通,但在查看代码后,查询需要查询中的 2 列,因此添加 * 的人都做得太过分了,但如果我添加该列会产生错误,同样添加第三列会产生同样的错误:

SELECT col2, col3 FROM tbl WHERE col1 IS NULL GROUP BY col2 ORDER BY col2
SELECT col1, col2, col3 FROM tbl WHERE col1 IS NULL GROUP BY col2 ORDER BY col2

谁能告诉我为什么最后一个查询不起作用?我无法从 docs 破译原因,但这是获得我需要的结果集所需的最少查询。

运行 Adminer 中的查询我得到这个错误

Error in query (1055): Expression #2 of SELECT list is not in GROUP BY 
clause and contains nonaggregated column 'name.table.column' 
which is not functionally dependent on columns in GROUP BY clause; this is 
incompatible with sql_mode=only_full_group_by

它不起作用的原因是因为您需要使用 GROUP BYORDER BY 中的选择标准之一。所以如果你想按 col1 分组,你需要这样做:

SELECT col1, col2, col3     
   FROM tbl     
   WHERE 
      col1 IS NULL     
   GROUP BY col1     
   ORDER BY col1 
;

如果不选择那个字段,你基本上是在说 "Hey go get me every phone number in California" 然后在你得到它之后你说 "Now order them by first name and group them by last name" 并且 DBMS 说 "but... I don't have any of that"

试试这个

SELECT col2, col3 FROM tbl WHERE col1 IS NULL GROUP BY col2, col3 ORDER BY col2, col3

这个查询:

SELECT *
FROM tbl
WHERE col1 IS NULL
GROUP BY col1
ORDER BY col1;

从来没有真正奏效过。它可能 似乎 起作用,但你很幸运。 SELECT 中有未聚合的列。这些来自任意行。

可以做这样的事情来从其他列中获取值:

SELECT col1, min(col2), min(col3)
FROM tbl t
WHERE col1 IS NULL AND
GROUP BY col1
ORDER BY col1;

使用GROUP BY需谨慎。一旦你理解了 GROUP BY 的作用,你就会自己知道问题所在。它对您的数据进行聚合,或者换句话说,它通过对原始条目进行一些操作并创建新的减少数量的条目来减少您的数据,这些条目已经应用了一些聚合函数(SUM、COUNT、AVG 等)

您在 GROUP BY 子句中提供的字段表示您要达到的 aggregation/roll-up 级别。

SELECT col2, col3 FROM tbl WHERE col1 IS NULL GROUP BY col1 ORDER BY col1

此处您尝试在 col1 级别进行聚合,这意味着对于列 col1 中存在的每个不同值,将对您在 SELECT 子句(此处为 col2col3),以便在输出中您在 col1 中具有非重复值以及 col2col3 根据您应用的函数(SUM、COUNT、AVG 等)针对每个不同的 col1 值。

如何应用这个功能?这就是您上面的查询中缺少的内容。要解决它,您需要对 SELECT 子句中存在但 GROUP BY 子句中不存在的字段应用一些聚合函数。以 SUM 为例,试试这个:

SELECT SUM(col2), SUM(col3) FROM tbl WHERE col1 IS NULL GROUP BY col1 ORDER BY col1

或者为了更好的想法,删除 WHERE 过滤器并通过 运行 检查输出:

SELECT col1, SUM(col2), SUM(col3) FROM tbl GROUP BY col1 ORDER BY col1

此外,您的其他查询的原因

SELECT col2 FROM tbl WHERE col1 IS NULL GROUP BY col2 ORDER BY col2

有效是因为您不需要对 GROUP BY 子句中存在的字段(此处 col2)应用聚合。

首先,当query() returns false时,您应该找出错误是什么。您似乎在使用 PDO,因此我将引导您访问此页面:http://php.net/manual/en/pdo.error-handling.php

TL;DR - 您应该启用 PDO 异常,否则您需要编写代码来检查每次调用 query()prepare()execute() 的结果以查看如果发生错误。如果是这样,请使用 errorInfo() 找出实际错误。做任何其他事情都是盲目的!

Error in query (1055): Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'webvictoria.cats_oct.matchLink' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

这是一个常见问题。查看数十个标记为 的问题。

我猜你刚刚升级到 MySQL 5.7。 MySQL 5.7 默认启用严格模式,所以我猜你刚刚升级了。在 MySQL 5.6 之前,严格模式是可选的,默认情况下不启用。

参见:https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html

您不能编写模棱两可的查询。如果你GROUP BY col2,col1和col3应该使用每组行组中的哪个值?模棱两可。

没有严格模式,MySQL 从组中选择任意行。在严格模式下,它恢复到标准的 SQL 行为,并且不允许模棱两可的查询。顺便说一句,这就是大多数其他品牌的 SQL 数据库的行为方式。

要修复它,您必须遵循以下规则:select 列表中的每一列都必须是以下之一:

  • GROUP BY 子句中的一列
  • 一列在功能上依赖于 GROUP BY 子句中的列(因此只能有一个值)
  • 用于聚合函数,如 MIN()、MAX()、COUNT()、SUM()、AVG() 或 GROUP_CONCAT()

为了 "getting the code working again." 有些人选择在 MySQL 5.7 中禁用严格模式,但它 没有 工作——它只是给出模棱两可的结果就像 MySQL 5.7 之前一样。

最好修复查询的逻辑。