首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL ORDER BY、GROUP BY、HAVING 深度對比:分組聚合、排序與過濾的正確語義與執行順序

     編輯:MySQL 資料庫相關知識

三者是 SQL 查詢的核心子句,但語義、執行順序、搭配規則常被混淆。本文從定義、標準語法順序、聚合函數依賴、WHERE vs HAVING 差異四個維度徹底釐清。

核心定義速查

子句核心語義必需條件典型搭配
ORDER BY結果集行排序指定排序列ASC/DESC、多級排序
GROUP BY數據分組聚合至少一個分組列 + 聚合函數SUM/COUNT/AVG/MIN/MAX
HAVING分組後過濾條件含聚合函數配合 GROUP BY 使用

標準 SQL 執行順序(關鍵!)

SELECT select_list
FROM table_source
WHERE search_condition      -- 1. 行級過濾(無聚合)
GROUP BY group_by_expression -- 2. 分組
HAVING search_condition      -- 3. 組級過濾(可含聚合)
ORDER BY order_list          -- 4. 最終排序

記憶口訣: Where → Group → Having → Order(先過濾行,再分組,再過濾組,最後排序)。

GROUP BY 鐵律:非聚合列必須出現在 GROUP BY 中

錯誤示例:

SELECT A, B FROM t GROUP BY A;  -- B 未聚合且未在 GROUP BY,報錯

正確寫法:

SELECT A, COUNT(B) AS cnt FROM t GROUP BY A;  -- B 經聚合
-- 或
SELECT A, B FROM t GROUP BY A, B;  -- B 納入分組鍵

WHERE vs HAVING:行級 vs 組級過濾

維度WHEREHAVING
執行階段GROUP BY 之前GROUP BY 之後
可用列表原始列SELECT 列表中的列/別名 + 聚合函數
聚合函數不可用可用(常用)
典型場景業務條件過濾聚合指標篩選

綜合實戰示例

需求:統計各部門薪資總和 > 50萬 的部門,按總薪資降序。

SELECT dept_name, SUM(salary) AS total_salary, COUNT(*) AS emp_cnt
FROM employees
WHERE status = '在職'                    -- 1. 先過濾在職員工
GROUP BY dept_name                       -- 2. 按部門分組
HAVING SUM(salary) > 500000              -- 3. 過濾薪資總和>50萬的組
ORDER BY total_salary DESC;              -- 4. 最後排序

常見誤區避坑

  1. 在 WHERE 中用聚合函數 → 語法錯誤,改用 HAVING。
  2. GROUP BY 列少於 SELECT 非聚合列 → 嚴格模式報錯,補全 GROUP BY 或加聚合。
  3. HAVING 條件可下推 WHERE 時未下推 → 如 HAVING dept_name='銷售部' 應改為 WHERE dept_name='銷售部',減少分組運算量。
  4. ORDER BY 用別名 vs 位置號 → 推薦別名(可讀性),位置號(ORDER BY 2)易因 SELECT 列變動出錯。

理清三者語義邊界與執行順序,寫出的 SQL 既正確又高效。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved