GROUP BY 與 JOIN 是多維分析的雙引擎。本文系統講解分組查詢六大模式(單獨、GROUP_CONCAT、聚合函數、HAVING、多字段、WITH ROLLUP)、內外連接三類語法與語義差異,並給出演練場景。
| 模式 | 語法 | 結果特徵 | 適用場景 |
|---|---|---|---|
| 單獨使用 | GROUP BY sex | 每組僅顯示第一行(非聚合列不確定) | 快速檢查分組鍵分布 |
| + GROUP_CONCAT | GROUP BY sex, GROUP_CONCAT(name) | 每組非聚合列拼接展示 | 審計、導出明細清單 |
| + 聚合函數 | GROUP BY sex, COUNT(*) | 每組統計指標 | 報表、儀表盤 |
| + HAVING | GROUP BY sex HAVING COUNT(*) >= 3 | 分組後過濾 | 篩選大客戶、活躍用戶 |
| 多字段分組 | GROUP BY dept_id, sex | 層級聚合(先部門再性別) | 多維度交叉分析 |
| + WITH ROLLUP | GROUP BY sex WITH ROLLUP | 末行顯示總計(分組鍵為 NULL) | 報表總計行自動生成 |
-- 1. 內連接:僅返回雙方匹配行
SELECT e.id, e.name, e.dept_id, d.dept_name
FROM employee e
INNER JOIN department d ON e.dept_id = d.dept_id;
-- 等價舊寫法(不推薦)
SELECT e.id, e.name, e.dept_id, d.dept_name
FROM employee e, department d
WHERE e.dept_id = d.dept_id;
-- 2. 左連接:保留左表所有行,右表無匹配填 NULL
SELECT e.id, e.name, e.dept_id, d.dept_name
FROM employee e
LEFT JOIN department d ON e.dept_id = d.dept_id;
-- 3. 右連接:保留右表所有行(可由左連接交換表順序替代)
SELECT e.id, e.name, e.dept_id, d.dept_name
FROM employee e
RIGHT JOIN department d ON e.dept_id = d.dept_id;
-- 等價
SELECT e.id, e.name, e.dept_id, d.dept_name
FROM department d
LEFT JOIN employee e ON e.dept_id = d.dept_id;
| 業務問題 | 連接類型 | 關鍵點 |
|---|---|---|
| 查詢有部門的員工 | INNER JOIN | 雙方必須存在 |
| 查詢所有員工及其部門(含無部門) | LEFT JOIN | 左表全保留 |
| 查詢所有部門及其員工(含空部門) | RIGHT JOIN / LEFT JOIN 交換順序 | 右表全保留 |
| 查詢無部門員工 + 空部門 | FULL OUTER JOIN (MySQL 不支持) | LEFT JOIN UNION RIGHT JOIN 模擬 |
-- 每個部門員工數(含 0 人部門)
SELECT d.dept_name, COUNT(e.id) AS emp_cnt
FROM department d
LEFT JOIN employee e ON d.dept_id = e.dept_id
GROUP BY d.dept_id, d.dept_name;
-- 每門課程最高分
SELECT c.course_name, MAX(g.score) AS max_score
FROM course c
LEFT JOIN grade g ON c.course_id = g.course_id
GROUP BY c.course_id, c.course_name;
GROUP BY 默認排序(隱式 ORDER BY),大數據集加 ORDER BY NULL 禁用排序LEFT JOIN 時左表應為小表;INNER JOIN 優化器自動選擇驅動表GROUP_CONCAT 受 group_concat_max_len (默認 1024) 限制,大文本需調大WITH ROLLUP 不支持 ORDER BY,需外層包裹排序FULL OUTER JOIN:查詢所有員工與部門,含無部門員工與空部門分組聚合與多表連接是 SQL 表達業務邏輯的核心組合。建議以「業務問題 → 關係代數 → SQL 寫法 → 執行計劃驗證」四步法練習,逐步建立從需求到高性能 SQL 的直覺映射。