使用和滥用 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
子句)必须包含列
- 在
GROUP BY
条款中提到,或 - 聚合函数如
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
下工作。