使用和滥用 GROUP BY

 SELECT item.item_id, item.name,     /* not SQL-92 */ 
        COUNT(*) number_of_uses
  FROM item 
  JOIN uses ON item.item_id, uses.item_id
 GROUP BY item.item_id

将在名为 item 的表中显示行,并在名为 uses 的表中显示相关行的计数。这很好用,但不幸的是它不是标准的 SQL-92。

为什么不?因为 GROUP BY 查询中的 SELECT 子句(和 ORDER BY 子句)必须包含列

  1. GROUP BY 条款中提到,或
  2. 聚合函数如 COUNT()MIN() 等。

这个例子的 SELECT 条款提到了 item.name,这是一个不符合这些标准的列。如果 SQL 模式包含 ONLY_FULL_GROUP_BY,MySQL 5.6 及更早版本将拒绝此查询。

通过更改 GROUP BY 子句,可以使此示例查询符合 SQL-92 标准,如下所示。

SELECT item.item_id, item.name, 
       COUNT(*) number_of_uses
  FROM item 
  JOIN uses ON item.item_id, uses.item_id
 GROUP BY item.item_id, item.name

如果 DBMS 可以证明它们与组密钥列之间存在功能依赖性,则后面的 SQL-99 标准允许 SELECT 语句省略组密钥中的未聚合列。因为 item.name 在功能上依赖于 item.item_id,所以最初的例子是有效的 SQL-99。MySQL 在 5.7 版本中获得了功能依赖性证明 。原始示例在 ONLY_FULL_GROUP_BY 下工作。