MySQL中WITH ROLLUP的具體使用
今天第一次知道有這個用法,記錄一下吧
WITH ROLLUP 是 MySQL 中一個非常實用的 GROUP BY 擴(kuò)展功能,用于生成分層匯總報表。它確實不像基礎(chǔ) SQL 語句那樣常見,但在數(shù)據(jù)分析場景中非常強大。
1. ROLLUP 的基本功能
WITH ROLLUP 會在 GROUP BY 分組結(jié)果的基礎(chǔ)上:
- 為每個分組層級添加小計行
- 最后添加一個總計行
- 生成的匯總行中,被匯總的列顯示為 NULL
2. 實際案例解析
假設(shè)有銷售數(shù)據(jù)表 sales_data:
| category | region | sales | |----------|---------|-------| | 電子產(chǎn)品 | 華北 | 1000 | | 電子產(chǎn)品 | 華東 | 1500 | | 家居用品 | 華北 | 800 | | 家居用品 | 華南 | 1200 |
執(zhí)行你的示例查詢:
SELECT
IFNULL(category, 'All Categories') as category,
IFNULL(region, 'All Regions') as region,
SUM(sales) as total_sales
FROM sales_data
GROUP BY category, region WITH ROLLUP;
結(jié)果將是:
| category | region | total_sales | |----------------|-------------|-------------| | 電子產(chǎn)品 | 華北 | 1000 | | 電子產(chǎn)品 | 華東 | 1500 | | 電子產(chǎn)品 | All Regions | 2500 | ← 電子產(chǎn)品小計 | 家居用品 | 華北 | 800 | | 家居用品 | 華南 | 1200 | | 家居用品 | All Regions | 2000 | ← 家居用品小計 | All Categories | All Regions | 4500 | ← 總計行
3. ROLLUP 的層級關(guān)系
對于 GROUP BY a, b, c WITH ROLLUP,它會生成:
- 基礎(chǔ)分組 (a, b, c)
- 一級小計 (a, b, NULL)
- 二級小計 (a, NULL, NULL)
- 總計 (NULL, NULL, NULL)
4. 實際應(yīng)用場景
(1) 銷售報表分析
SELECT
YEAR(order_date) as year,
QUARTER(order_date) as quarter,
MONTH(order_date) as month,
SUM(amount) as revenue
FROM orders
GROUP BY YEAR(order_date), QUARTER(order_date), MONTH(order_date)
WITH ROLLUP;
(2) 庫存分類統(tǒng)計
SELECT
warehouse,
product_type,
COUNT(*) as item_count,
SUM(quantity) as total_quantity
FROM inventory
GROUP BY warehouse, product_type WITH ROLLUP;
5. 高級用法技巧
(1) 識別匯總行
SELECT
category,
region,
SUM(sales) as total_sales,
GROUPING(category) as is_category_summary,
GROUPING(region) as is_region_summary
FROM sales_data
GROUP BY category, region WITH ROLLUP;
(2) 多維度交叉分析
SELECT
IFNULL(category, 'Total') as category,
SUM(CASE WHEN region='華北' THEN sales END) as north,
SUM(CASE WHEN region='華東' THEN sales END) as east,
SUM(sales) as subtotal
FROM sales_data
GROUP BY category WITH ROLLUP;
6. 與其他數(shù)據(jù)庫的對比
| 功能 | MySQL | SQL Server | Oracle | PostgreSQL |
|---|---|---|---|---|
| WITH ROLLUP | ? | ? | ? | ? |
| GROUPING SETS | ? | ? | ? | ? |
| CUBE | ? | ? | ? | ? |
在不支持 ROLLUP 的數(shù)據(jù)庫中,可以使用 UNION ALL 組合多個查詢來模擬。
7. 性能注意事項
- ROLLUP 會在服務(wù)器端生成額外的匯總行
- 大數(shù)據(jù)集時可能影響性能
- 考慮在應(yīng)用層實現(xiàn)類似邏輯(特別是Web分頁時)
8. 為什么你可能沒見過?
- 業(yè)務(wù)場景限制:常規(guī)CRUD操作不需要
- 替代方案:有些團(tuán)隊用應(yīng)用代碼計算匯總
- 報表工具:BI工具通常內(nèi)置了匯總功能
- 新版本特性:不是所有開發(fā)者都熟悉較新的SQL功能
ROLLUP 特別適合需要生成:
? 分類小計報表
? 多層匯總統(tǒng)計
? 財務(wù)或銷售分析報表
下次需要做分層匯總時,可以嘗試使用這個強大的功能。
案例:SQL175 有取消訂單記錄的司機(jī)平均評分
select
COALESCE(driver_id, '總體') as driver_id,
round(avg(grade), 1) as grade
from
tb_get_car_order
where
driver_id in (
select
driver_id
from
tb_get_car_record
join tb_get_car_order using (order_id)
where
year(order_time) = 2021
and month(order_time) = 10
and start_time is null
)
and grade is not null
group by
driver_id
WITH
ROLLUP
ORDER BY
driver_id IS NULL,
driver_id

SQL 筆記:WITH ROLLUP 和 ORDER BY 的配合使用
問題背景
當(dāng)使用 WITH ROLLUP 生成匯總行時,匯總行的分組列值為 NULL。如果我們想給這個 NULL 值賦予一個有意義的名稱(如"總體"或"總計"),并在排序時確保這一行顯示在最后,需要注意一些技巧。
解決方案
1. 使用 COALESCE 或 IFNULL 重命名匯總行
SELECT
COALESCE(driver_id, '總體') AS driver_id,
ROUND(AVG(grade), 1) AS grade
FROM ...
GROUP BY driver_id WITH ROLLUP
2. 正確排序確保匯總行在最后
當(dāng)添加 ORDER BY 時,簡單的按列排序會導(dǎo)致"總體"行按字母順序排列,而不是顯示在最后。解決方案:
方法一:利用 NULL 值排序特性
ORDER BY driver_id IS NULL, driver_id
• driver_id IS NULL:對于匯總行返回 1,其他行返回 0
• 這樣匯總行會排在最后,其他行按 driver_id 排序
方法二:使用 CASE 表達(dá)式
ORDER BY CASE WHEN driver_id IS NULL THEN 1 ELSE 0 END, driver_id
• 更顯式地控制排序優(yōu)先級
關(guān)鍵點
- WITH ROLLUP 生成的匯總行的分組列值為 NULL
- 使用 COALESCE/IFNULL 可以美化顯示這個 NULL 值
- 排序時需要特殊處理才能確保匯總行在最后
- ORDER BY column IS NULL 是一個簡潔有效的解決方案
到此這篇關(guān)于MySQL中WITH ROLLUP的具體使用的文章就介紹到這了,更多相關(guān)MySQL WITH ROLLUP內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于Mysql8.0版本驅(qū)動getTables返回所有庫的表問題淺析
這篇文章主要給大家介紹了關(guān)于Mysql 8.0版本驅(qū)動getTables返回所有庫的表問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-12-12
mysql 操作總結(jié) INSERT和REPLACE
用于操作數(shù)據(jù)庫的SQL一般分為兩種,一種是查詢語句,也就是我們所說的SELECT語句,另外一種就是更新語句,也叫做數(shù)據(jù)操作語句。2009-07-07
Mysql保持現(xiàn)有內(nèi)容在后面增加內(nèi)容的sql語句
這篇文章主要介紹了Mysql保持現(xiàn)有內(nèi)容在后面增加內(nèi)容的sql語句,需要的朋友可以參考下2017-05-05
文章介紹了MySQL慢查詢排查的步驟,包括查看當(dāng)前正在運行的事務(wù)狀態(tài)、查看線程狀態(tài)、殺死線程、輔助判斷命令、開啟慢查詢?nèi)罩竞烷_啟通用查詢?nèi)罩?/div> 2025-02-02最新評論

