只使用group by子句和聚合函数是无法同时得出小计和合计的,想要同时得到,可以使用grouping运算符。

同时得到合计行

使用group by 只能得到每组的合计值,不能得到总计:

select product_type, sum(sale_price)
from Product
group by product_type;

SQL SERVER合计HANSHU sql 合计行_聚合函数

通常计算合计是分别计算出合计行和按照商品种类进行汇总的结果,然后通过union all连接在一起:

select '合计' as product_type, sum(sale_price)
from Product
union all
select product_type, sum(sale_price)
from Product
group by product_type;

SQL SERVER合计HANSHU sql 合计行_聚合函数_02

rollup:同时得出合计和小计

grouping运算符包含以下3种:1.rollup

                                                 2.cube

                                                 3.grouping sets

rollup的使用方法:

select product_type, sum(sale_price) as sum_price
from Product
group by rollup(product_type);

SQL SERVER合计HANSHU sql 合计行_字符串_03

多出来的一行就是所有的合计。

该运算符的作用,就是一次计算出不同聚合键组合的结果。使用rollup其实进行了如下两种组合的汇总结果:

1.group by()用来计算所有的总和

2.group by(product_type)用来分组计算总和

1中的group by()表示没有聚合键,也就相当于没有group by子句(这时会得到全部数据的合计行记录),该合计行记录称为超级分组记录。

将登记日期添加到聚合键中:

select product_type, regist_date, sum(sale_price) as sum_price
from Product
group by rollup(product_type, regist_date);

SQL SERVER合计HANSHU sql 合计行_聚合函数_04

使用rollup时多出了最上方的合计行以及3条不同商品种类的小计行(也就是未使用登记日期作为聚合键的记录),这4行就是超级分组记录。

相当于3种聚合:1.group by()

                           2.group by(product_type)

                           3.group by(product_type, regist_date)

grouping函数:让null更加容易分辨

为了避免混淆null值,sql提供了grouping函数来判断超级记录分组记录的null。该函数在其参数列的值为超级分组记录所产生的null时返回1,其他情况返回0.

select grouping(product_type) as product_type, grouping(regist_date) as regist_date, sum(sale_price) as sum_price
from Product
group by rollup(product_type, regist_date);

SQL SERVER合计HANSHU sql 合计行_字符串_05

在超级记录分组记录的键值中插入恰当的字符串:

select case when grouping(product_type) = 1
            then '商品种类 合计'
			else product_type end as product_type,
	   case when grouping(regist_date) = 1
	        then '登记日期 合计'
			else cast(regist_date as varchar(16)) end as regist_date,
	   sum(sale_price) as sum_price
from Product
group by rollup(product_type, regist_date);

SQL SERVER合计HANSHU sql 合计行_运算符_06

这里需要注意的是,由于cast表达式所有分支的返回值必须一致,所以要将日期转换为字符串。

cube:用数据来搭积木

select case when grouping(product_type) = 1
            then '商品种类 合计'
			else product_type end as product_type,
	   case when grouping(regist_date) = 1
	        then '登记日期 合计'
			else cast(regist_date as varchar(16)) end as regist_date,
	   sum(sale_price) as sum_price
from Product
group by cube(product_type, regist_date);

SQL SERVER合计HANSHU sql 合计行_SQL SERVER合计HANSHU_07

这里的cube按以下4种方式聚合:1.group by()

                                                     2.group by(product_type)

                                                     3.group by(regist_date)

                                                     4.group by(product_type, regist_date)

所谓cube,就是将group by子句中的聚合键的所有可能的组合的汇总结果集中到一个结果中。因此,组合的个数就是2的n次方(n为聚合键的个数)。

grouping sets:取得期望的意思

select case when grouping(product_type) = 1
            then '商品种类 合计'
			else product_type end as product_type,
	   case when grouping(regist_date) = 1
	        then '登记日期 合计'
			else cast(regist_date as varchar(16)) end as regist_date,
	   sum(sale_price) as sum_price
from Product
group by grouping sets(product_type, regist_date);

SQL SERVER合计HANSHU sql 合计行_运算符_08

grouping sets用于从中取出个别条件对应的不固定结果(不常用)