同一張表、同一個 WHERE 條件,EXISTS (SELECT id ...) 回傳 0 筆,但 EXISTS (SELECT MAX(id) ...) 卻回傳全表行數——顯然被誤判為 TRUE。
「MySQL ignores the SELECT list in such a subquery, so it makes no difference.」
—— MySQL 官方文檔
實測 MySQL 5.6.31 / 5.7.14 均存在此 Bug。
CREATE TABLE t3(id INT, t DATETIME); INSERT INTO t3 VALUES(1, '20160812'); -- 正確:id=2 不存在,回傳空集 SELECT 1 FROM dual WHERE EXISTS (SELECT id FROM t3 WHERE id=2); -- Empty set -- 錯誤:加上 MAX() 卻回傳 1 SELECT 1 FROM dual WHERE EXISTS (SELECT MAX(id) FROM t3 WHERE id=2); -- +---+ -- | 1 | -- +---+
| 查詢 | 重寫後 SQL (SHOW WARNINGS) | 判斷 |
|---|---|---|
EXISTS (SELECT id ...) | WHERE 0 | 正確判定 FALSE |
EXISTS (SELECT MAX(id) ...) | WHERE 1 | 錯誤判定 TRUE |
優化器將聚合函數子查詢錯誤重寫為常數 1,導致語意改變。
已提交:Bug #82562
SELECT * 或 SELECT 1,避免任何聚合/函數操作ABS()、FLOOR() 不觸發此 Bug,但為求穩健仍建議統一用 *MySQL 8.0.13+ 已修復(優化器重寫邏輯重構)。5.7/5.6 維護版本需自行規避。