濫用 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 錯誤並拒絕執行此類查詢。