Mat*_*hew 15 mysql sql group-by
鉴于下表' foo
'
ID | First Name | Last Name
----------------------------
67 John Smith
----------------------------
67 Bill Jacobs
Run Code Online (Sandbox Code Playgroud)
什么first_name
和last_name
将下面的查询返回,为什么?
SELECT * FROM foo WHERE ID = 67 GROUP BY ID
Run Code Online (Sandbox Code Playgroud)
Bil*_*win 27
MySQL任意选择一行.在实践中,常用的MySQL存储引擎相对于物理存储返回组中第一行的值.
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 |
+----+----------+
Run Code Online (Sandbox Code Playgroud)
其他人都认为MySQL允许您运行此查询,即使它具有任意且可能具有误导性的结果.SQL标准和大多数其他RDBMS供应商不允许这种模糊的GROUP BY查询.这就是所谓的单值规则:在选择列表中的所有列必须在GROUP BY标准明确一部分,否则内部的聚合函数,例如COUNT()
,MAX()
等等.
MySQL支持一种SQL模式ONLY_FULL_GROUP_BY
,如果您尝试运行违反SQL标准语义的查询,则会使MySQL返回错误.
AFAIK,SQLite是唯一允许分组查询中含糊不清的列的其他RDBMS.SQLite返回组中最后一行的值:
select * from foo group by category;
6|bar
3|foo
Run Code Online (Sandbox Code Playgroud)
我们可以想象查询不会模糊,但仍然违反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;
Run Code Online (Sandbox Code Playgroud)
没有合理的方法可以产生模棱两可的结果.如果我们GROUP BY foo的主键,foo中的每一行都有自己的组.所以来自foo的任何列只能在组中有一个值.如果组由foo的主键定义,即使加入foo中外键引用的另一个表,每个组也只能有一个值.
MySQL和SQLite相信您可以设计逻辑上明确的查询.形式上,select-list中的每一列必须是GROUP BY条件中列的函数依赖项.如果你不遵守这个,那就是你的错.:-)
标准SQL更加严格,不允许一些的查询可能是明确的-可能是因为它会过于复杂的RDBMS以确保一般.
MySQL 的分组依据与标准 SQL 行为不一致,MySQL 使获取其他列变得很容易,但同时你永远无法确定你会得到哪一列。
更新:参考此页面: http://dev.mysql.com/doc/refman/5.0/en/group-by-handling.html
使用此功能时,每个组中的所有行对于从 GROUP BY 部分省略的列应具有相同的值。服务器可以自由地从组中返回任何值,因此结果是不确定的,除非所有值都相同。
很可能会选择第二(最后)行的名字和姓氏。
您可以添加 ORDER BY 子句来提示您希望如何对分组的行进行排序。