我更新了mysql,我从MySQL 5.6.17版本转到版本5.7.14
因为我的SQL查询有错误
实际上,我的许多查询都是这样的:
SELECT count (id) as nbr, lic from prep WHERE key = '18'
Run Code Online (Sandbox Code Playgroud)
我有这个错误:
1140 - 在没有GROUP BY的聚合查询中,SELECT列表的表达式#2包含非聚合列'operator.preparation.orig_lic'; 这与sql_mode = only_full_group_by不兼容
经过一些研究,我了解到Mysql 5.7.14默认激活ONLY_FULL_GROUP_BY
为什么默认启用?
什么是最佳解决方案(性能)?禁用ONLY_FULL_GROUP_BY或在我的查询中添加"分组依据"?
谢谢
Ahm*_*aki 12
only_full_group_by = on告诉 MySQL 引擎:GROUP BY
当你对显示什么结果有疑问并抛出错误时不要申请。仅当命令明确告诉您要做什么时才应用它。即当命令完整且完整时!
only_full_group_by = off告诉 MySQL 引擎:始终应用GROUP BY
,如果您对选择的结果有疑问,请随机选择一个!
使用GROUP BY
得当是不会关掉的 !
例子:
表:用户
id | name
----------------
1 ali
2 john
3 ali
Run Code Online (Sandbox Code Playgroud)
在列GROUP BY
上使用时name
:
SELECT * FROM users GROUP BY name;
Run Code Online (Sandbox Code Playgroud)
有两种可能的结果:
1 ali
2 john
Run Code Online (Sandbox Code Playgroud)
或者
2 john
3 ali
Run Code Online (Sandbox Code Playgroud)
MYSQL不知道选择什么结果!因为有不同的id
s 但两者都有name=ali
。
解决方案1:
只选择name
字段:
SELECT name FROM users GROUP BY name;
Run Code Online (Sandbox Code Playgroud)
结果:
ali
john
Run Code Online (Sandbox Code Playgroud)
这是一个完美的解决方案。删除令人GROUP BY
困惑的列。这意味着你知道你在做什么。通常,您不需要
这些列,但如果您需要它们,请转到解决方案 3!
解决方案2:
关闭only_full_group_by
。MYSQL 将随机向您显示两种可能的结果之一!(如果你真的不在乎id
它会选择什么也没关系)
解决方案3
使用Aggregate
类似MIN()
,的函数MAX()
来帮助 MYSQL 决定它必须选择什么。
例如,我想要最小值id
:
SELECT MIN(id), name FROM users GROUP BY name;
Run Code Online (Sandbox Code Playgroud)
结果:
1 ali
2 john
Run Code Online (Sandbox Code Playgroud)
它将选择ali
具有最小值的行id
。
正确的解决方案是添加您分组的列:
SELECT count (id) as nbr, lic
from prep
WHERE key = '18'
group by lic
Run Code Online (Sandbox Code Playgroud)
对于性能,这取决于您拥有的索引。
这ONLY_FULL_GROUP_BY
是 SQL 中聚合函数的正常行为,采用 5.7 以避免对非聚合列结果的临时结果产生歧义。
“最佳”解决方案是做正确的事情并通过添加来修复查询group by
,而不是覆盖抛出的错误。如果用ONLY_FULL_GROUP_BY
错误覆盖错误,您的经历将消失,但是这样做可能会导致两个新错误:
包含非聚集值的聚集值的意外结果,这是您的错误试图避免的问题。
无法在其他环境上执行查询。如果您需要切换设置或将代码提供给不使用此数据库的其他人,查询将再次引发错误。如果您习惯于改写错误或其他错误,则您的代码可能对其他人不可用,从而严重削弱了代码的实用性。
通常,如果收到错误,请修复它,而不仅仅是告诉编译器/优化器忽略它。