GROUP BY 敘述句 (SQL GROUP BY Statement)

GROUP BY 敘述句用於將查詢結果中特定欄位值相同的記錄分為若干個群組。它通常搭配聚合函數 (Aggregate Functions) 使用,對每個群組分別計算彙總值,而每個群組只會返回一列結果。

若沒有使用 GROUP BY,聚合函數會將整個結果集視為一個群組,只返回單一彙總值。

常用的聚合函數

函數說明
COUNT()計算記錄數量
SUM()計算數值總和
AVG()計算平均值
MAX()找出最大值
MIN()找出最小值

GROUP BY 語法 (Syntax)

SELECT column1, column2, ..., aggregate_function(column)
FROM table_name
[WHERE condition]
GROUP BY column1, column2, ...
[HAVING group_condition]
[ORDER BY column];

重要規則:

  • SELECT 中列出的非聚合欄位,通常都必須出現在 GROUP BY 子句中。
  • GROUP BY 會在 WHERE 篩選之後、HAVINGORDER BY 之前執行。

GROUP BY 用法範例 (Example)

orders 資料表:

O_IdPriceCustomer
11000張一
22000王二
3500李三
41300張一
51800王二

範例 1:計算每位顧客的訂單金額總和

SELECT Customer, SUM(Price) AS TotalAmount
FROM orders
GROUP BY Customer;

結果:

CustomerTotalAmount
張一2300
王二3800
李三500

Customer 欄位值相同的記錄被分為一組,然後對每組的 Price 欄位加總。

範例 2:計算每位顧客的訂單數量

SELECT Customer, COUNT(*) AS OrderCount
FROM orders
GROUP BY Customer;

結果:

CustomerOrderCount
張一2
王二2
李三1

範例 3:搭配 WHERE 條件

先篩選資料,再進行分組:

SELECT Customer, SUM(Price) AS TotalAmount
FROM orders
WHERE Price >= 1000
GROUP BY Customer;

結果:

CustomerTotalAmount
張一2300
王二3800

李三的訂單金額 500 小於 1000,在 WHERE 階段就被過濾掉了。

多欄位分組

GROUP BY 後面指定多個欄位時,只有所有指定欄位的值都相同的記錄才會被分為同一組。

sales 資料表:

YearRegionAmount
2023北部1000
2023北部1500
2023南部800
2024北部1200
2024南部900
SELECT Year, Region, SUM(Amount) AS TotalSales
FROM sales
GROUP BY Year, Region
ORDER BY Year, Region;

結果:

YearRegionTotalSales
2023北部2500
2023南部800
2024北部1200
2024南部900

GROUP BY 與 NULL 值

GROUP BY 會將所有 NULL 值視為同一組:

SELECT Region, COUNT(*) AS Count
FROM customers
GROUP BY Region;
-- Region 為 NULL 的記錄會被分為一組

GROUP BY 與 DISTINCT 的差異

GROUP BYDISTINCT
可搭配聚合函數僅用於去除重複
返回分組後的彙總結果返回不重複的記錄
-- 使用 DISTINCT 取得不重複的客戶
SELECT DISTINCT Customer FROM orders;

-- 使用 GROUP BY 取得每位客戶的統計資訊
SELECT Customer, COUNT(*), SUM(Price) FROM orders GROUP BY Customer;

SQL 執行順序

了解 SQL 的執行順序有助於理解 GROUP BY 的運作:

  1. FROM - 決定資料來源
  2. WHERE - 篩選記錄
  3. GROUP BY - 將記錄分組
  4. HAVING - 篩選分組
  5. SELECT - 選取欄位
  6. DISTINCT - 去除重複
  7. ORDER BY - 排序結果
  8. LIMIT / TOP - 限制筆數

GROUP BY 的注意事項

SELECT 欄位必須在 GROUP BY 中

-- 錯誤:O_Id 不在 GROUP BY 中,也不是聚合函數
SELECT Customer, O_Id, SUM(Price)
FROM orders
GROUP BY Customer;

-- 正確
SELECT Customer, SUM(Price)
FROM orders
GROUP BY Customer;

💡 MySQL 的特殊行為: MySQL 在某些模式下允許 SELECT 包含不在 GROUP BY 中的欄位,但這會返回不確定的結果。建議遵循標準 SQL 規範。

搭配 HAVING 篩選分組

HAVING 子句用於篩選分組後的結果:

SELECT Customer, SUM(Price) AS TotalAmount
FROM orders
GROUP BY Customer
HAVING SUM(Price) > 1000;

相關主題