下午在写三表联查的 SQL,遇到
Expression #6 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'Test.Goods_Status.is_send_msg' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
这样的问题,然后调查了一下,好像是 MySQL5.7 引入的 only_full_group_by 特性导致的,网上给出的大部分解释是 select 中的属性需要包含在 group by 中,即:
Group By 正确的用法
myql 的 group by 语法为:
select 选取分组中的列 + 聚合函数 from 表名称 group by 分组的列
从语法格式来看,是先有分组,再确定检索的列,检索的列只能是参加分组了的列。
所以问题中,group by 后的 a,b,c 是先确定的,而 select 后面的字段是可变的
正确的语句
select a,b,c from table_name group by a,b,c,d;
select a,b from table_name group by a,b,c;
select a,max(a) from table_name group by a,b,c;
以下是错误的
select a,b,c from table_name group by a,b;
select a,b,c from table_name group by a;
我这边原先出错的 SQL 是这样的:
SELECT Goods_Information.goods_id,
Goods_Information.express_number,
phone,
container_number,
pick_up_code,
(CASE WHEN is_send_msg= '0'
AND is_pick_up= '0' THEN '0' WHEN is_send_msg= '1'
AND is_pick_up= '0' THEN '1' END) AS status,
MAX(operation_time)
FROM Goods_Information
LEFT JOIN Goods_Status ON Goods_Information.goods_id= Goods_Status.goods_id
LEFT JOIN Operation_record ON Goods_Information.goods_id= Operation_record.goods_id
WHERE is_pick_up= '0'
GROUP BY Goods_Information.goods_id
ORDER BY Goods_Information.goods_id
然后我自己看了一下报错,半蒙半猜的试着改成了这样:
SELECT Goods_Information.goods_id,
Goods_Information.express_number,
phone,
container_number,
pick_up_code,
(CASE WHEN is_send_msg= '0'
AND is_pick_up= '0' THEN '0' WHEN is_send_msg= '1'
AND is_pick_up= '0' THEN '1' END) AS status,
MAX(operation_time)
FROM Goods_Information
LEFT JOIN Goods_Status ON Goods_Information.goods_id= Goods_Status.goods_id
LEFT JOIN Operation_record ON Goods_Information.goods_id= Operation_record.goods_id
WHERE is_pick_up= '0'
GROUP BY Goods_Information.goods_id,
is_send_msg
ORDER BY Goods_Information.goods_id
即在 GROUP BY 中加入了 is_send_msg 这个属性,然后就能正常工作了,但是这跟网上对这个 only_full_group_by 模式的解释不一样啊,有一等蒙了。
另外将 select 中 有关 is_send_msg 的属性都删去也能查出结果(猜测:select 主表中的属性,使用 group by 时不需要将属性添加进 group by 中?),也不符合上面说的 select 中的属性需要全部包含在 group by 中的原则啊。
is_pick_up 属性和 is_send_msg 是在一张表上的,按理说这 2 个属性地位应该是一样的啊,但是因为 is_pick_up 在 where 语句被使用了,所以不需要进入 groupBy 了?实际上去掉 Where 后 is_pick_up 这个属性也被提示同样的错误了。Select 中其他几项属性是主表中的,所以不需要加入 group By ? 所以这个 only_full_group_by 到底是个什么模式呢?有人说跟 oracle group by 是一样的,但是测试下来不一样啊?希望有大佬帮忙解释一下。
官方的说明好像也没提到具体情况,但是给了 一个 ANY_VALUE() 函数来在不关闭这个模式的情况下,使得 SQL 正常工作(也可能是我英语太渣没看懂,学渣自卑) : https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.