滥用 GROUP BY 返回不可预测的结果 Murphys Law
SELECT item.item_id, uses.category, /* nonstandard */
COUNT(*) number_of_uses
FROM item
JOIN uses ON item.item_id, uses.item_id
GROUP BY item.item_id
将在名为 item 的表中显示行,并在名为 uses 的表中显示相关行的计数。它还将显示名为 uses.category
的列的值。
此查询在 MySQL 中有效(在出现 ONLY_FULL_GROUP_BY
标志之前)。它使用 MySQL 对 GROUP BY
的非标准扩展 。
但查询有一个问题:如果 uses
表中的几行与 JOIN
子句中的 ON
条件匹配,MySQL 将从其中一行返回 category
列。哪排?查询的编写者和应用程序的用户不会事先知道这一点。从形式上讲,它是不可预测的 :MySQL 可以返回它想要的任何值。
不可预测就像是*随机的,*有一个显着的区别。人们可能期望随机选择随时改变。因此,如果选择是随机的,你可以在调试或测试期间检测到它。在不可预知的结果更糟糕的是:MySQL 的每次使用查询时返回相同的结果,*直到没有。*有时它是 MySQL 服务器的新版本导致不同的结果。有时这是一个不断增长的表格导致问题。什么可能出错,会出错,当你不指望它时。这就是所谓的墨菲定律 。
MySQL 团队一直在努力让开发人员更难犯这个错误。5.7 序列中较新版本的 MySQL 有一个名为 ONLY_FULL_GROUP_BY
的 sql_mode
标志。设置该标志后,MySQL 服务器返回 1055 错误并拒绝运行此类查询。