前几天,QQ学习群有个小伙伴问我一个使用SQL分层汇总的问题。
今天正好分享下。
需求描述
在数据报表开发的工作中,经常会遇到需要对数据进行分组汇总的情况。
假设有一个销售数据表sales,包含列region(地区)、month(月份),以及sales_amount(销售金额)。
模型结构及样例数据如下:
create table sales(
region varchar(20),
month varchar(20),
amount decimal(10,2)
);
insert into sales values('北京','10月',12.26);
insert into sales values('深圳','10月',12.26);
insert into sales values('上海','10月',12.26);
insert into sales values('北京','11月',12.26);
insert into sales values('深圳','11月',12.26);
insert into sales values('上海','11月',12.26);
假如,需要计算每个地区每个月的销售总额,并且还要计算每个地区整体的销售总额。也就是说,在查询出明细数据的同时,还要计算出不同层次的小计和总计。
是不是很复杂繁琐?
如果使用多个SQL语句,那么可以按层次GROUP BY汇总,最后把每层汇总结果UNION ALL起来。
可是,如果层次很多呢?是不是需要写很多个SQL才能拼接出最终的结果?
这时候,使用RULLUP函数,可以让我们轻松实现这个需求。
RULLUP函数的基本语法
先了解一下RULLUP函数的含义及其基本语法。
RULLUP是一种分组函数,用于生成分层次的汇总报表。它可以按照指定的列或表达式进行分组,并计算出每个分组的汇总值。
在ORACLE数据库中(其他数据库也有类似写法),RULLUP函数的基本语法如下:
SELECT 列1, 列2, 列3, ..., 列n, 聚合函数(列)
FROM 表名
GROUP BY 列1, 列2, 列3, ..., 列n WITH ROLLUP;
在上面的语法中,可以指定需要进行分组的列(可以是多列)以及要进行汇总计算的列(使用聚合函数,如SUM、COUNT等)。然后,将需要分层汇总的列放在GROUP BY的ROLLUP函数中,就可以启用RULLUP功能。
RULLUP函数的使用示例
对于文章开头分层计算销售额的需求,可以使用如下SQL语句实现:
select
region,
month,
sum(amount)
from sales
group by rollup(region,month) ;
上面的SQL,我已经在SQL在线运行网站SQL Fiddle中运行通过。截图如下:
从上面的结果可以看到,ROLLUP函数不仅生成了地区的小计,最后还生成了总计。而且,数据还按地区及月份自动做了排序,是不是很智能、很贴心。
关于SQL在线运行网站,省去了我们安装数据库,搭建环境的烦恼,而且还有多种数据库可以使用,真的是非常方便,简直是SQL新手必备。我已经在之前的文章中有过介绍了。