首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL 學習筆記:深入理解 GROUP BY 與 HAVING

     編輯:關於SqlServer

核心概念

  • 聚合函數:SUM、COUNT、MAX、MIN、AVG 等,作用於多筆記錄,回傳單一值。
  • GROUP BY:將結果集按指定欄位分組,每組只能回傳一列;非分組欄位必須包裹在聚合函數中。
  • WHERE:在分組前過濾原始記錄。
  • HAVING:在分組後過濾聚合結果。

執行順序

FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT

記憶口訣:先篩選行,再分組,再篩選組。

實戰範例(以世界國家表 bbc 為例)

範例 1:各地區總人口與總面積

SELECT region, SUM(population) AS total_pop, SUM(area) AS total_area
FROM bbc
GROUP BY region;

邏輯:按 region 分組 → 每組計算 SUM。

範例 2:僅顯示面積超過 1,000,000 的地區

SELECT region, SUM(population) AS total_pop, SUM(area) AS total_area
FROM bbc
GROUP BY region
HAVING SUM(area) > 1000000;

關鍵:不能用 WHERE 過濾 SUM(area),因原始表無「地區總面積」這欄位;必須用 HAVING 對聚合結果過濾。

常見錯誤與正確寫法對照

錯誤寫法錯誤原因正確寫法
SELECT dept, COUNT(*) FROM emp WHERE COUNT(*) > 5 GROUP BY deptWHERE 不能用聚合函數SELECT dept, COUNT(*) FROM emp GROUP BY dept HAVING COUNT(*) > 5
SELECT dept, name FROM emp GROUP BY deptname 非分組欄位且未聚合SELECT dept, GROUP_CONCAT(name) FROM emp GROUP BY dept (MySQL) 或 STRING_AGG(name, ',') (PG/SQL Server)
SELECT dept, SUM(sal) FROM emp GROUP BY dept, name多加 name 導致過度分組若只需按部門統計,GROUP BY dept 即可

進階:GROUP BY 搭配 ROLLUP / CUBE(SQL Server / Oracle / PostgreSQL)

SELECT dept, job, SUM(sal)
FROM emp
GROUP BY ROLLUP (dept, job);  -- 產生小計與總計行

附錄:分頁查詢經典寫法(補充自原文)

-- 寫法 1:NOT IN 子查詢(效能較差)
SELECT TOP m * FROM tablename WHERE id NOT IN (SELECT TOP n id FROM tablename);

-- 寫法 2:暫存表 + ROWCOUNT(舊版 SQL Server)
SELECT TOP m * INTO #temp FROM tablename ORDER BY col;
SET ROWCOUNT n;
SELECT * FROM #temp ORDER BY col DESC;

-- 寫法 3:巢狀 TOP(通用)
SELECT TOP n * FROM (SELECT TOP m * FROM tablename ORDER BY col) a ORDER BY col DESC;

-- 現代寫法(MySQL 8.0+ / PG / SQL Server 2012+)
SELECT * FROM tablename ORDER BY col OFFSET n ROWS FETCH NEXT m ROWS ONLY;

小結

  • GROUP BY 是「縱向切分」,HAVING 是對切分後的「組」進行過濾。
  • SELECT 清單中出現的非聚合欄位,必須出現在 GROUP BY 中(嚴格模式下)。
  • 分頁查詢現代語法 OFFSET ... FETCH 更標準、可讀、效能佳。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved