MySQL GROUP BY 教學:從基礎語法到效能最佳化完整指南

1. 前言:GROUP BY 概述

在資料庫中處理大規模資料時,GROUP BY 子句是一個強大的工具,可以有效率地進行彙總與整理。GROUP BY 會根據特定欄位將資料分組,並對每個群組進行彙總。例如,在計算各商品類別的銷售總額時,使用這個子句即可輕鬆取得所需的結果。

透過使用 GROUP BY 子句,可以將資料整理成更直觀的形式,並搭配聚合函數(SUMCOUNTAVG 等)進行更深入的分析。

2. GROUP BY 的基本用法

使用 GROUP BY 子句時,會依指定的欄位將資料分組,並針對每個群組進行彙總。這讓我們可以快速取得依特定分類或條件的摘要與統計資料。

基本語法

SELECT 欄位名稱, 聚合函數(欄位名稱)
FROM 資料表名稱
GROUP BY 欄位名稱;

範例

若要計算商品類別的銷售總額,可以使用以下查詢:

SELECT product_category, SUM(sales_amount)
FROM sales
GROUP BY product_category;

此查詢會計算並顯示每個商品類別的銷售總額。

結果範例

product_categorySUM(sales_amount)
家電100,000
食品50,000
衣服75,000

3. GROUP BY 與聚合函數的組合

將 GROUP BY 與聚合函數結合,可以將資料依群組彙整,並取得群組的統計數據。在 MySQL 中常用的聚合函數有:

  • SUM():計算數值資料的總和
  • COUNT():計算資料筆數
  • AVG():計算數值資料的平均值
  • MAX():取得最大值
  • MIN():取得最小值

範例查詢

若要同時取得商品類別的銷售總額與銷售筆數,可以使用以下查詢:

SELECT product_category, SUM(sales_amount), COUNT(*)
FROM sales
GROUP BY product_category;

此查詢會針對 product_category 計算銷售總額與銷售筆數。

4. 使用 HAVING 子句篩選

HAVING 子句用於對 GROUP BY 分組後的結果再進行條件篩選。其特點是可以基於聚合函數的結果進行過濾,這與在聚合前就進行篩選的 WHERE 子句不同。

範例查詢

例如,若只想取得銷售總額大於 1000 的類別,可以使用:

SELECT product_category, SUM(sales_amount)
FROM sales
GROUP BY product_category
HAVING SUM(sales_amount) > 1000;

此查詢會僅返回銷售總額超過 1000 的商品類別。

5. GROUP BY 搭配 ORDER BY

使用 GROUP BY 進行分組後,若要將結果排序,可搭配 ORDER BY 子句。ORDER BY 可依指定欄位的值進行升序(ASC)或降序(DESC)排列。

範例查詢

以下範例會依銷售總額由高到低排序商品類別:

SELECT product_category, SUM(sales_amount)
FROM sales
GROUP BY product_category
ORDER BY SUM(sales_amount) DESC;

此查詢會依銷售額多寡排序商品類別。

6. 進階用法:GROUP BY 與 WITH ROLLUP

WITH ROLLUP 可以附加在 GROUP BY 後,用來在分組結果之外,自動取得總合計。這樣不僅能看到每個群組的彙總,也能快速取得整體的統計數據,非常適合用於業務報表或摘要報告。

範例查詢

以下查詢會顯示各城市的銷售總額,並在最後附加總合計:

SELECT city, SUM(sales_amount)
FROM sales
GROUP BY city WITH ROLLUP;

此查詢會列出各城市的銷售總額,並在最後多顯示全部城市的銷售總額。

7. GROUP BY 與 DISTINCT 的差異

DISTINCTGROUP BY 都能整理資料,但用途不同。DISTINCT 會移除重複的資料,僅保留唯一值;而 GROUP BY 則是將資料分組並進行彙總。

範例比較

使用 DISTINCT 取得不重複的商品類別:

SELECT DISTINCT product_category
FROM sales;

使用 GROUP BY 取得各商品類別的銷售筆數:

SELECT product_category, COUNT(*)
FROM sales
GROUP BY product_category;

也就是說,DISTINCT 僅移除重複項目,而 GROUP BY 則能進行群組統計。

8. MySQL 中 GROUP BY 的效能最佳化

在處理大規模資料集時,GROUP BY 的效能調整非常重要。以下是幾個常見的優化方法:

1. 使用索引

若在 GROUP BY 的欄位上建立索引,可以加快查詢與分組的效率。

CREATE INDEX idx_category ON sales(product_category);

合理使用索引能大幅提升效能。

2. 調整記憶體參數

處理大量資料時,調整 MySQL 的記憶體參數能提升速度。像是 sort_buffer_sizetmp_table_size 的值可適度加大:

SET GLOBAL sort_buffer_size = 2M;
SET GLOBAL tmp_table_size = 64M;

增加記憶體使用量能減少磁碟寫入,縮短處理時間。

3. 簡化查詢

過度複雜的查詢會降低效能。過多的 JOIN 或子查詢會造成延遲,建議保持查詢簡單,並移除不必要的欄位或條件。

4. 利用版本新功能

從 MySQL 8.0 開始,除了傳統的排序式分組外,還支援雜湊式分組,通常比排序方式更快:

SET optimizer_switch = 'hash_join=on';

5. 使用查詢快取

若使用 MySQL 5.7 或更早版本,可以利用查詢快取來提升重複查詢的速度:

SET GLOBAL query_cache_size = 16M;
SET GLOBAL query_cache_type = 1;

6. 考慮資料分割(Partitioning)

透過 MySQL 的分割表(Partitioning),可將大型資料表拆分成多個部分,加快查詢速度:

ALTER TABLE sales PARTITION BY RANGE (YEAR(sale_date)) (
    PARTITION p0 VALUES LESS THAN (2021),
    PARTITION p1 VALUES LESS THAN (2022),
    PARTITION p2 VALUES LESS THAN (2023)
);

9. 總結:GROUP BY 的高效應用

GROUP BY 子句是 SQL 中非常實用的工具,可以依群組進行彙總與分析。本文介紹了基本用法、HAVING 子句與 ORDER BY 的搭配、進階的 WITH ROLLUP,並探討了效能優化的方法。

此外,透過索引、記憶體調整、雜湊式分組、查詢快取與資料分割等技術,能有效提升大規模資料處理的效率。依據 MySQL 版本採用適合的功能與設定,能讓日常的資料分析更快更有效率。