1

我正在更新一个旧网站,但其中一个查询不再起作用:

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

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

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

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

在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
4

5 回答 5

3

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

您在子句中提供的字段GROUP BY代表您要进行的聚合/汇总级别。

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

在这里,您尝试在col1级别进行聚合,这意味着对于 column 中存在的每个不同值,将对您在子句(此处, )col1中提供的其他一些列进行一些操作,以便在输出中您具有非重复值根据您应用的函数(SUM、COUNT、AVG 等),每个不同的值的in和一些汇总值和针对每个不同值的汇总值。SELECTcol2col3col1col2col3col1

你如何应用这个功能?这就是您的上述查询中缺少的内容。要解决它,您需要对子句中存在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

工作是因为您不需要将聚合应用于子句col2中存在的字段(此处) 。GROUP BY

于 2017-12-07T18:47:23.267 回答
2

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

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

查询中的错误 (1055):SELECT 列表的表达式 #2 不在 GROUP BY 子句中,并且包含在功能上不依赖于 GROUP BY 子句中的列的非聚合列“webvictoria.cats_oct.matchLink”;这与 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 数据库的行为方式。

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

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

有些人选择在 MySQL 5.7 中禁用严格模式是为了“让代码再次工作”。但它不起作用——它只是像 MySQL 5.7 之前那样给出模棱两可的结果。

最好修复查询的逻辑。

于 2017-12-07T18:50:50.420 回答
1

这个查询:

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;
于 2017-12-07T18:41:50.067 回答
0

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

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

如果不选择该字段,您基本上是在说“嘿,把加利福尼亚的每个电话号码都给我”然后在您说“现在按名字排序并按姓氏分组”并且 DBMS 说“但是......我什么都没有”

于 2017-12-07T18:28:48.823 回答
-1

试试这个

SELECT col2, col3 FROM tbl WHERE col1 IS NULL GROUP BY col2, col3 ORDER BY col2, col3
于 2017-12-07T18:29:26.713 回答