给出下表“foo
”
ID | First Name | Last Name
----------------------------
67 John Smith
----------------------------
67 Bill Jacobs
以下查询返回的内容为first_name
和last_name
,为什么?
SELECT * FROM foo WHERE ID = 67 GROUP BY ID
答案 0 :(得分:27)
MySQL任意选择一行。实际上,常用的MySQL存储引擎会返回组中 first 行中与物理存储相关的值。
create table foo (id serial primary key, category varchar(10));
insert into foo (category) values
('foo'), ('foo'), ('foo'), ('bar'), ('bar'), ('bar');
select * from foo group by category;
+----+----------+
| id | category |
+----+----------+
| 4 | bar |
| 1 | foo |
+----+----------+
其他人都认为MySQL允许您运行此查询,即使它具有任意且可能具有误导性的结果。 SQL标准和大多数其他RDBMS供应商不允许这种模糊的GROUP BY查询。这称为单值规则:select-list中的所有列必须明确地成为GROUP BY标准的一部分,或者在聚合函数内部,例如, COUNT()
,MAX()
等
MySQL支持SQL模式ONLY_FULL_GROUP_BY
,如果您尝试运行违反SQL标准语义的查询,则会使MySQL返回错误。
AFAIK,SQLite是唯一允许分组查询中含糊不清的列的其他RDBMS。 SQLite从组中的 last 行返回值:
select * from foo group by category;
6|bar
3|foo
我们可以想象查询不会模糊,但仍然违反SQL标准语义。
SELECT foo.*, parent_of_foo.*
FROM foo JOIN parent_of_foo
ON (foo.parent_id = parent_of_foo.parent_id)
GROUP BY foo_id;
没有合理的方法可以产生模棱两可的结果。如果我们GROUP BY foo的主键,foo中的每一行都有自己的组。因此foo中的任何列只能在组中有一个值。如果组由foo的主键定义,即使加入foo中外键引用的另一个表,每个组只能有一个值。
MySQL和SQLite相信您可以设计逻辑上明确的查询。形式上,select-list中的每一列必须是GROUP BY条件中列的功能依赖。如果你不遵守这个,那就是你的错。 : - )
标准SQL更严格,并且不允许某些可以明确的查询 - 可能是因为它对于RDBMS来说通常过于复杂。
答案 1 :(得分:4)
MySQLs group by与标准的SQL行为不一致,MySQL可以很容易地获得其他列但同时你永远无法确定你会得到哪一个。
更新: 参考此页面: http://dev.mysql.com/doc/refman/5.0/en/group-by-handling.html
使用此功能时,所有行都在 每个组应具有相同的值 对于从中省略的列 GROUP BY部分。服务器是免费的 从组中返回任何值,所以 结果是不确定的,除非 所有的价值都是一样的。
答案 2 :(得分:3)
这是未定义的,这将导致你获得。
我一直想知道为什么甚至允许这种行为。真的,我希望这样的代码只会产生一个错误(最好是一个可辨认的错误,没有那个通常的MySQL“你的语句有问题,但我不知道在哪里”。)
答案 3 :(得分:0)
很可能会选择第二行(最后一行)的名字和姓氏。
您可以添加ORDER BY子句,以提供有关如何对分组行进行排序的提示。
答案 4 :(得分:0)
在标准SQL中,此SQL应该失败,服务器处理器错误类似于
“firstname和lastname不能包含在select子句中,除非它们也在Group By中,或者是聚合函数的一部分。”
MySql是否实际为此返回数据?
答案 5 :(得分:0)
MySQLs group by与标准SQL行为不一致, MySQL可以让你轻松获得其他列,但同时也是如此 永远不能确定你会得到哪一个。
真。实际上它更多地与postgres中的SELECT DISTINCT ON模式相对应,除了这允许你指定在distinctization(?)之前的行的顺序,因此你将获得哪一行(即最新,最旧,无论如何)。
注意“符合sql”模式下的MySQL将拒绝带有未指定列的GROUP BY,如示例所示。