In 这本书 https://rads.stackoverflow.com/amzn/click/com/0072465638我目前正在阅读有关数据库的课程,给出了以下使用聚合运算符的非法查询的示例:
找出最年长水手的姓名和年龄。
考虑以下尝试回答此查询:
SELECT S.sname, MAX(S.age)
FROM Sailors S
此查询的目的不仅是返回最大年龄,还返回
也是该年龄水手的名字。然而,这个查询是
SQL 中非法——如果 SELECT 子句使用聚合操作,则
它必须使用only聚合操作,除非查询包含 GROUP BY 子句!
一段时间后,在使用 MySQL 进行练习时,我遇到了类似的问题,并犯了与上述错误类似的错误。然而,MySQL 并没有抱怨,只是吐出了一些表,后来发现这些表并不是我所需要的。
上面的查询在 SQL 中真的非法,但在 MySQL 中合法,如果是,为什么会这样?
在什么情况下需要进行这样的查询?
对问题的进一步阐述:
问题不在于 SELECT 中提到的所有属性是否也应该在 GROUP BY 中提及。
这就是为什么上面的查询,使用属性以及对属性的聚合操作,而不使用任何 GROUP BY 在 MySQL 中是合法的。
假设 Sailors 表如下所示:
+----------+------+
| sname | age |
+----------+------+
| John Doe | 30 |
| Jane Doe | 50 |
+----------+------+
然后查询将返回:
+----------+------------+
| sname | MAX(S.age) |
+----------+------------+
| John Doe | 50 |
+----------+------------+
现在谁需要那个? John Doe 不是 50 岁,他已经 30 岁了!
正如书中的引文所述,这是首次尝试获取最年长水手的姓名和年龄,在本例中,Jane Doe 50 岁。
SQL会说这个查询是非法的,但MySQL只是继续执行并吐出“垃圾”。
谁需要这样的结果?
为什么 MySQL 允许给新手设置这个小陷阱呢?
顺便说一句,这是 MySQL 的默认行为。但可以通过设置 ONLY_FULL_GROUP_BY 服务器模式来更改my.ini
文件或会话中 -
SET sql_mode = 'ONLY_FULL_GROUP_BY';
SELECT * FROM sakila.film_actor GROUP BY actor_id;
Error: 'sakila.film_actor.film_id' isn't in GROUP BY
ONLY_FULL_GROUP_BY http://dev.mysql.com/doc/refman/5.1/en/server-sql-mode.html#sqlmode_only_full_group_by- 不允许查询的选择列表引用未在 GROUP BY 子句中命名的非聚合列。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)