当前位置: 代码网 > it编程>数据库>Mysql > MySQL中WITH ROLLUP的具体使用

MySQL中WITH ROLLUP的具体使用

2025年07月17日 Mysql 我要评论
今天第一次知道有这个用法,记录一下吧with rollup 是 mysql 中一个非常实用的 group by 扩展功能,用于生成分层汇总报表。它确实不像基础 sql 语句那样常见,但在数据分析场景中

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

with rollup 是 mysql 中一个非常实用的 group by 扩展功能,用于生成分层汇总报表。它确实不像基础 sql 语句那样常见,但在数据分析场景中非常强大。

1. rollup 的基本功能

with rollup 会在 group by 分组结果的基础上:

  • 为每个分组层级添加小计行
  • 最后添加一个总计行
  • 生成的汇总行中,被汇总的列显示为 null

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. 性能注意事项

  • rollup 会在服务器端生成额外的汇总行
  • 大数据集时可能影响性能
  • 考虑在应用层实现类似逻辑(特别是web分页时)

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内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网! 

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com