Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL WITH ROLLUP

MySQL中WITH ROLLUP的具体使用

作者:羚风雯

本文主要介绍了MySQL中WITH ROLLUP的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

今天第一次知道有这个用法,记录一下吧

WITH ROLLUP 是 MySQL 中一个非常实用的 GROUP BY 扩展功能,用于生成分层汇总报表。它确实不像基础 SQL 语句那样常见,但在数据分析场景中非常强大。

1. ROLLUP 的基本功能

WITH ROLLUP 会在 GROUP BY 分组结果的基础上:

2. 实际案例解析

假设有销售数据表 sales_data

| category | region  | sales |
|----------|---------|-------|
| 电子产品 | 华北    | 1000  |
| 电子产品 | 华东    | 1500  |
| 家居用品 | 华北    | 800   |
| 家居用品 | 华南    | 1200  |

执行你的示例查询:

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;

结果将是:

| category       | region      | total_sales |
|----------------|-------------|-------------|
| 电子产品      | 华北        | 1000        |
| 电子产品      | 华东        | 1500        |
| 电子产品      | All Regions | 2500        | ← 电子产品小计
| 家居用品      | 华北        | 800         |
| 家居用品      | 华南        | 1200        |
| 家居用品      | All Regions | 2000        | ← 家居用品小计
| All Categories | All Regions | 4500        | ← 总计行

3. ROLLUP 的层级关系

对于 GROUP BY a, b, c WITH ROLLUP,它会生成:

  1. 基础分组 (a, b, c)
  2. 一级小计 (a, b, NULL)
  3. 二级小计 (a, NULL, NULL)
  4. 总计 (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) 库存分类统计

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. 与其他数据库的对比

功能MySQLSQL ServerOraclePostgreSQL
WITH ROLLUP
GROUPING SETS
CUBE

在不支持 ROLLUP 的数据库中,可以使用 UNION ALL 组合多个查询来模拟。

7. 性能注意事项

8. 为什么你可能没见过?

  1. 业务场景限制:常规CRUD操作不需要
  2. 替代方案:有些团队用应用代码计算汇总
  3. 报表工具:BI工具通常内置了汇总功能
  4. 新版本特性:不是所有开发者都熟悉较新的SQL功能

ROLLUP 特别适合需要生成:
✅ 分类小计报表
✅ 多层汇总统计
✅ 财务或销售分析报表

下次需要做分层汇总时,可以尝试使用这个强大的功能。

案例: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

• 更显式地控制排序优先级

关键点

  1. WITH ROLLUP 生成的汇总行的分组列值为 NULL
  2. 使用 COALESCE/IFNULL 可以美化显示这个 NULL 值
  3. 排序时需要特殊处理才能确保汇总行在最后
  4. ORDER BY column IS NULL 是一个简洁有效的解决方案

到此这篇关于MySQL中WITH ROLLUP的具体使用的文章就介绍到这了,更多相关MySQL WITH ROLLUP内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

您可能感兴趣的文章:
阅读全文