MySQL中WITH ROLLUP的具體使用
今天第一次知道有這個用法,記錄一下吧
WITH ROLLUP
是 MySQL 中一個非常實用的 GROUP BY 擴展功能,用于生成分層匯總報表。它確實不像基礎 SQL 語句那樣常見,但在數(shù)據(jù)分析場景中非常強大。
1. ROLLUP 的基本功能
WITH ROLLUP
會在 GROUP BY 分組結(jié)果的基礎上:
- 為每個分組層級添加小計行
- 最后添加一個總計行
- 生成的匯總行中,被匯總的列顯示為 NULL
2. 實際案例解析
假設有銷售數(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 的層級關系
對于 GROUP BY a, b, c WITH ROLLUP
,它會生成:
- 基礎分組 (a, b, c)
- 一級小計 (a, b, NULL)
- 二級小計 (a, NULL, NULL)
- 總計 (NULL, NULL, NULL)
4. 實際應用場景
(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 會在服務器端生成額外的匯總行
- 大數(shù)據(jù)集時可能影響性能
- 考慮在應用層實現(xiàn)類似邏輯(特別是Web分頁時)
8. 為什么你可能沒見過?
- 業(yè)務場景限制:常規(guī)CRUD操作不需要
- 替代方案:有些團隊用應用代碼計算匯總
- 報表工具:BI工具通常內(nèi)置了匯總功能
- 新版本特性:不是所有開發(fā)者都熟悉較新的SQL功能
ROLLUP 特別適合需要生成:
? 分類小計報表
? 多層匯總統(tǒng)計
? 財務或銷售分析報表
下次需要做分層匯總時,可以嘗試使用這個強大的功能。
案例:SQL175 有取消訂單記錄的司機平均評分
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 的配合使用
問題背景
當使用 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. 正確排序確保匯總行在最后
當添加 ORDER BY 時,簡單的按列排序會導致"總體"行按字母順序排列,而不是顯示在最后。解決方案:
方法一:利用 NULL 值排序特性
ORDER BY driver_id IS NULL, driver_id
• driver_id IS NULL:對于匯總行返回 1,其他行返回 0
• 這樣匯總行會排在最后,其他行按 driver_id 排序
方法二:使用 CASE 表達式
ORDER BY CASE WHEN driver_id IS NULL THEN 1 ELSE 0 END, driver_id
• 更顯式地控制排序優(yōu)先級
關鍵點
- WITH ROLLUP 生成的匯總行的分組列值為 NULL
- 使用 COALESCE/IFNULL 可以美化顯示這個 NULL 值
- 排序時需要特殊處理才能確保匯總行在最后
- ORDER BY column IS NULL 是一個簡潔有效的解決方案
到此這篇關于MySQL中WITH ROLLUP的具體使用的文章就介紹到這了,更多相關MySQL WITH ROLLUP內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
MySQL字符集 GBK、GB2312、UTF8區(qū)別 解決MYSQL中文亂碼問題
MYSQL中文亂碼問題原因有很多,腳本之家以前發(fā)布過很多相關文章,這篇文章介紹mysql相關的一些知識更詳細2012-08-08mysql5.7大量sleep進程常規(guī)處理方式及配置示例
這篇文章主要給大家介紹了關于mysql5.7大量sleep進程常規(guī)處理方式及配置的相關資料,sleep連接過多會嚴重消耗mysql服務器資源(主要是cpu,內(nèi)存),并可能導致mysql崩潰,需要的朋友可以參考下2023-08-08mysql中Table is read only的解決方法小結(jié)
本文章總結(jié)了關于在linux與windows中 mysql出現(xiàn)Table is read only解決辦法總結(jié),有需要的朋友可參考一下2013-01-01MySQL數(shù)據(jù)庫 1067錯誤號的解決方法
這篇文章主要介紹了MySQL數(shù)據(jù)庫 1067錯誤號的解決方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-12-12