SELECT column, aggregate_function
FROM table
[WHERE condition]
[GROUP BY expression]
[HAVING group_condition]
[ORDER BY column];
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT
WHERE 不能使用聚合函數/別名,HAVING 專門過濾分組後結果。
SELECT deptno, COUNT(*) AS cnt, AVG(sal) AS avg_sal
FROM emp
GROUP BY deptno;
SELECT deptno, AVG(sal) AS avg_sal
FROM emp
GROUP BY deptno
HAVING AVG(sal) > 2000; -- 僅顯示平均薪資>2000的部門
SELECT deptno, job, COUNT(*)
FROM emp
GROUP BY deptno, job;
SELECT deptno, COUNT(*) AS cnt
FROM emp
GROUP BY deptno
ORDER BY cnt DESC; -- 按統計結果排序
GROUP BY col1, col2 時,SELECT 列表可包含未分組、未聚合的列,MySQL 任意取一行值(ONLY_FULL_GROUP_BY 關閉時);sql_mode=ONLY_FULL_GROUP_BY,強制符合標準,避免數據不確定性。| 技巧 | 說明 |
|---|---|
| 索引覆蓋 GROUP BY 列 | 避免臨時表+文件排序 |
| WHERE 先過濾再分組 | 減少參與分組的行數 |
| 大表分組用近似算法 | APPROX_COUNT_DISTINCT (8.0+) 或應用層預聚合 |
| 避免 SELECT * | 僅選取分組列+聚合列 |