SQL語句SELECT COUNT(id), id, name FROM table在MySQL 5.5執行通過(返回第一行id/name),但在5.7+嚴格模式(ONLY_FULL_GROUP_BY)報錯:#1140 - Mixing of GROUP columns ... with no GROUP BY clause is illegal。本文剖析版本差異根因與規範寫法。
SELECT COUNT(id), id, name FROM `table`;
-- 5.5/5.6 (非嚴格模式):執行成功,id/name取結果集第一行(非確定性)
-- 5.7+ (預設 ONLY_FULL_GROUP_BY):報錯 1140
SELECT列表中非聚合欄位必須出現在GROUP BY中,或被聚合函數包裹sql_mode含ONLY_FULL_GROUP_BY,強制標準化| 需求 | 錯誤寫法 | 標準寫法 |
|---|---|---|
| 統計總數並顯示某行詳情 | SELECT COUNT(*), id, name FROM t | SELECT COUNT(*) OVER(), id, name FROM t LIMIT 1 (8.0+窗口函數)或分兩條SQL |
| 按分組統計並顯示分組屬性 | SELECT COUNT(*), id, name FROM t GROUP BY name | SELECT COUNT(*), id, name FROM t GROUP BY id, name(id,name需函數依賴) |
| 統計總數+任意一行樣本 | SELECT COUNT(*), id, name FROM t | SELECT (SELECT COUNT(*) FROM t) AS total, id, name FROM t LIMIT 1 |
GROUP BYSET SESSION sql_mode = REPLACE(@@sql_mode, 'ONLY_FULL_GROUP_BY', '')my.cnf中移除ONLY_FULL_GROUP_BYSELECT
id, name,
COUNT(*) OVER() AS total_cnt,
ROW_NUMBER() OVER(ORDER BY id) AS rn
FROM `table`
WHERE rn = 1; -- 取第一行並附帶總數
遵循標準SQL分組語義,拒絕「偏門寫法」,讓代碼在版本升級中平滑遷移。