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 查询。这被称为单值规则:选择列表中的所有列必须明确属于 GROUP BY 标准的一部分,或者位于聚合函数内,例如COUNT()
, MAX()
, etc.
MySQL支持SQL模式ONLY_FULL_GROUP_BY http://dev.mysql.com/doc/refman/5.1/en/server-sql-mode.html#sqlmode_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;
这不可能产生模棱两可的结果。如果我们按 foo 的主键进行 GROUP BY,则 foo 中的每一行都会获得自己的组。因此 foo 中的任何列在该组中只能有一个值。如果组是由 foo 的主键定义的,则即使连接到 foo 中的外键引用的另一个表,每个组也只能有一个值。
MySQL 和 SQLite 相信您能够设计逻辑上明确的查询。形式上,选择列表中的每一列都必须是功能依赖GROUP BY 条件中的列的数量。如果你不遵守这一点,那就是你的错。 :-)
标准 SQL 更加严格并且不允许某些查询could是明确的——可能是因为它对于 RDBMS 来说太复杂而无法确定。