假设我们想要找到具有特定名称的人的最大或最小年龄。
我们可以这样做:
select name, min(age) from users group by name;
select name, max(age) from users group by name;
min
和max
清楚地记录了其他集合函数。
(看似)实现上述目标的另一种方法如下:
select name, age from (select name, age from users order by age asc) sorted group by name;
select name, age from (select name, age from users order by age desc) sorted group by name;
虽然这有效,但它依赖于保证在构建结果集时,MySQL将从找到的第一条记录中获取内容,如果按字段分组有多条记录。
我找不到明确说明这种保证是真实的文件。是吗?
答案 0 :(得分:2)
引自官方documentation:
如果禁用ONLY_FULL_GROUP_BY,则为标准的MySQL扩展 GROUP BY的SQL使用允许选择列表,HAVING条件或 ORDER BY列表引用非聚合列,即使列 在功能上不依赖于GROUP BY列。这会导致MySQL 接受前面的查询。 在这种情况下,服务器是免费的 从每个组中选择任何值,所以除非它们相同,否则 选择的值是不确定的,这可能不是你想要的。 此外,不能从每个组中选择值 受添加ORDER BY子句的影响。发生结果集排序 选择值后,ORDER BY不会影响哪个 服务器选择的每个组中的值。 禁用 ONLY_FULL_GROUP_BY主要是因为有些人知道这一点 数据的属性,每个非聚合列中的所有值都不是 在GROUP BY中命名的每个组都是相同的。
因此,添加order by
并不能保证选择组中的第一个值。
答案 1 :(得分:1)
您的第一个版本是正确的。第二个版本显然是不正确的,并记录在案。以下是documentation中的示例:
SELECT o.custid, c.name, MAX(o.payment) FROM orders AS o, customers AS c [sic . . . why doesn't the documentation use JOIN???] WHERE o.custid = c.custid GROUP BY o.custid;
。 。
如果禁用
ONLY_FULL_GROUP_BY
,则对GROUP BY的标准SQL使用的MySQL扩展允许选择列表,HAVING
条件或ORDER BY
列表引用非聚合列,即使列在功能上不依赖于GROUP BY
列。这导致MySQL接受前面的查询。在这种情况下,服务器可以自由选择每个组中的任何值,因此除非它们相同,否则选择的值是不确定的,这可能不是您想要的。