在我的一个遗留应用程序中,有一个查询用于获取每个组的第一行,即。,
SELECT
columnPrimaryKey,
column1,
column2,
column3,
column4
FROM
(SELECT
columnPrimaryKey,
column1,
column2,
column3,
column4
FROM tableName
ORDER BY column4
) AS tbl
GROUP BY column3
上面的查询没有返回第一行(按column4排序),而是按主键列返回第一行,即。, columnPrimaryKey
.
这以前很管用。我记得我们升级了mysql,现在的版本是 5.7.22-log
.
我可以按以下方式重写查询,它将按预期工作:
SELECT
x.columnPrimaryKey,
x.column1,
x.column2,
x.column3,
x.column4
FROM tableName AS x INNER JOIN (
SELECT
MIN( column4 ) AS column4,
column3
FROM tableName
GROUP BY column3
) AS y ON x.column4 = y.column4 AND x.column3 = y.column3;
我已经查过了 sql_mode
因为它是 NO_ENGINE_SUBSTITUTION
.
有人能指出为什么第一个查询没有按预期工作吗?
3条答案
按热度按时间bnl4lu3b1#
评论太长,请在此添加以供参考:
从mysql文档:
mysql 5.7.5及更高版本实现了函数依赖性的检测。如果启用了only\ full\ group\ by sql模式(默认情况下是这样),mysql将拒绝select list、having condition或order by list引用的未聚合列,这些列既不在groupby子句中命名,也不在功能上依赖于它们(在5.7.5版本之前,mysql没有检测到函数依赖,默认情况下只启用\u full \u group \u by。)
如果仅禁用了\u full \u group by,则groupby的标准sql使用的mysql扩展允许select list、having condition或order by list引用未聚合的列,即使这些列在功能上不依赖于groupby列。这使mysql接受前面的查询。在这种情况下,服务器可以自由地从每个组中选择任何值,因此除非它们相同,否则选择的值是不确定的,这可能不是您想要的。此外,添加ORDERBY子句不能影响从每个组中选择值。结果集排序是在选择值之后进行的,排序依据不影响服务器在每个组中选择哪个值。如果您知道由于数据的某些属性,每个未在group by中命名的非聚集列中的所有值对于每个组都是相同的,则只禁用\u full \u group by非常有用。
更多信息请参见:https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html
hxzsmxv22#
第一个查询的选择列表:
不清楚,因为您正在中运行查询
GROUP BY
聚合模式,分组依据column3
. 这意味着对于的每个值只报告一条记录column3
. 如果给定的值有多条记录column3
,您没有告诉mysql要为其他列报告哪个值。因此,原则上,mysql可以自由选择它想要的任何值。究竟为什么会发生这种情况并不重要,因为你一直在使用第二种正确的方法前进。因此,一般来说,您应该记住,当您按一个或多个列进行分组时,您可以选择的列只有显示在中的列
GROUP BY
,或任何其他列,只要它出现在聚合函数中。x33g5p2x3#
这种行为是意料之中的。尤其是从<=5.7.5升级的情况。mysql已经默认开启了“onlyfullgroupby”模式。
SideNote:
在升级到新版本之前,最好先查看他们的“更改列表”。mysql说。
仅\u full \u group by \u
拒绝select list、having condition或order by list引用既不在group by子句中命名也不在功能上依赖于group by列(由group by列唯一确定)的未聚合列的查询。
这里有更多。
https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_only_full_group_by