萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL GROUP BY 深度解析:分組統計、ALL、WITH ROLLUP/CUBE、GROUPING 函數與執行順序

GROUP BY 基本語法

SELECT group_col, aggregate_func(col)
FROM table
WHERE filter_condition
GROUP BY group_col
HAVING group_condition
ORDER BY sort_col;

核心規則

  • SELECT 清單中的非聚合欄位必須出現在 GROUP BY 子句中。
  • 聚合函數:COUNT/SUM/AVG/MIN/MAX/GROUP_CONCAT 等。
  • WHERE 在分組前過濾行,HAVING 在分組後過濾組。

GROUP BY ALL(SQL Server 專用,MySQL 不支援)

保留 WHERE 過濾掉的分組,聚合值以 NULL/0 填充。MySQL 需用 LEFT JOIN 模擬。

WITH ROLLUP:層次化小計

SELECT dept_id, sex, COUNT(*) AS cnt
FROM employee
GROUP BY dept_id, sex WITH ROLLUP;

結果包含:
1. 明細行(dept+sex)
2. 部門小計(sex=NULL)
3. 總計(dept=NULL, sex=NULL)

GROUPING() 辨識小計行

SELECT dept_id, sex, COUNT(*) AS cnt,
       GROUPING(dept_id) AS g_dept,
       GROUPING(sex) AS g_sex
FROM employee
GROUP BY dept_id, sex WITH ROLLUP;
  • GROUPING(col)=1 表示該行為該欄位的小計行(NULL 由 ROLLUP 產生)。
  • 可用於 HAVING GROUPING(sex)=1 只取小計。

WITH CUBE:全維度組合(SQL Server/Oracle,MySQL 不支援)

產生所有欄位組合的小計。MySQL 可用多個 GROUPING SETS(8.0+)或 UNION ALL 模擬。

MySQL 8.0 GROUPING SETS

SELECT dept_id, sex, COUNT(*)
FROM employee
GROUP BY GROUPING SETS ((dept_id, sex), (dept_id), (sex), ());

等同 CUBE,但可精確控制組合。

執行順序(關鍵)

  1. FROM / JOIN
  2. WHERE
  3. GROUP BY
  4. 聚合函數計算
  5. HAVING
  6. SELECT(含別名)
  7. ORDER BY
  8. LIMIT

含義:WHERE 不能用聚合函數/別名;HAVING 可用聚合函數;ORDER BY 可用別名。

實戰範例:各折扣商品數 + 總計

SELECT COUNT(*) AS product_count, discount,
       GROUPING(discount) AS is_subtotal
FROM fruit
GROUP BY discount WITH ROLLUP;

結果:
3 | NULL | 0(無折扣組)
1 | 0.8 | 0
1 | 0.9 | 0
1 | 1.0 | 0
6 | NULL | 1(總計行,GROUPING=1 識別)

copyright © 萬盛學電腦網 all rights reserved