使用MySQL的GROUP BY时,有什么保证将结果放入哪些数据?

时间:2017-01-31 18:54:34

标签: mysql sql

假设我们想要找到具有特定名称的人的最大或最小年龄。

我们可以这样做:

select name, min(age) from users group by name;
select name, max(age) from users group by name;

minmax清楚地记录了其他集合函数。

(看似)实现上述目标的另一种方法如下:

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将从找到的第一条记录中获取内容,如果按字段分组有多条记录。

我找不到明确说明这种保证是真实的文件。是吗?

2 个答案:

答案 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接受前面的查询。在这种情况下,服务器可以自由选择每个组中的任何值,因此除非它们相同,否则选择的值是不确定的,这可能不是您想要的。