欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SqlServer中分组函数GROUPBY的扩展:all,cube,roolup与grouping

程序员文章站 2022-04-15 13:23:09
概述: GROUP BY很常见,无须解释。GROUP BY结合all, cube,roolup使用起来可以实现很多功能。在数据库报表、统计分析、仓库处理等OLAP(在线联机分析)...

概述:

GROUP BY很常见,无须解释。GROUP BY结合all, cube,roolup使用起来可以实现很多功能。在数据库报表、统计分析、仓库处理等OLAP(在线联机分析)场合使用GROUP BY及其扩展函数,再结合窗口函数,必将发挥巨大作用,以精简的程序实现强大的功能,起到事半功倍的效果。

具体说到GROUP BY 扩展功能中的CUBE和ROLLUP区别不太大,只是在基于GROUP BY 子句创建和汇总分组的可能的组合上有一定差别,CUBE将返回的更多的可能组合。如果在GROUP BY子句中有N个列或者是有N个表达式的话,SQLSERVER在使用CUBE的结果集上会返回2的N次幂个可能组合。

事例说明:

1、group by all

Transact-SQL 在 GROUP BY 子句中提供 ALL 关键字。只有在 SELECT 语句还包括 WHERE 子句时,ALL 关键字才有意义。

如果使用 ALL 关键字,则即使某些组不包含符合搜索条件的行,查询结果也将包括 GROUP BY 子句生成的所有组。如果不使用 ALL 关键字,则包含 GROUP BY 子句的 SELECT 语句仅显示包含符合搜索条件的行的组。

举例:找出机械学院中的人数。
SELECT
DEPTName,
sum(len) as Total
FROM HRYGZD
WHERE DEPTName= '机械学院'
GROUP BY ALL DEPTName

Name Total
varchar(36) int
机械学院 1220
生物学院 NULL
物理学院 NULL
化工学院 NULL

2、group by cube

group by cube(字段1,字段2,字段3) 可以写成group by (字段1,字段2,字段3) with cube。通常Group By语句是按照其后所跟的所有字段进行分组,而如果加入了CUBE关键字以后,那么系统将根据所有字段进行分组的基础上,还会通过对所有这些分组字段所有可能存在的组合形成的分组条件进行分组计算。如果Group by(a,b,c) with cube

那么分组计算时可分为如下几种分组:(a,b,c),(a,b),(b,c),(a,c),(a),(b),(c),()。

结合使用grouping函数可以用于列中数据存在NULL时的辨别, grouping(列)如果是数据列,则计算值为0,如果为汇总列计算值为1。

举例:

SELECT
CASE grouping(CODE)
WHEN 1 THEN 'all'
ELSE CODE END AS CODE,
CASE grouping(ID)
WHEN 1 THEN 'all'
ELSE IDEND AS ID,
count(*) AS '合计'
FROM LeaveApply
GROUP BY cube(CODE,ID)

----having 过滤
分组((CODE,humanid),(CODE),(humanid),(),2^2 = 4种分组

CODE ID 合计
varchar(36) varchar(36) int
201605270017 0160135e-b693-4a42-b62b-506dd0d9fda5 1
201605270027 0160135e-b693-4a42-b62b-506dd0d9fda5 1
all 0160135e-b693-4a42-b62b-506dd0d9fda5 2
201609200030 02338f05-1b8c-4cfb-9493-dae4c8434977 1
all 02338f05-1b8c-4cfb-9493-dae4c8434977 1
201607190004 0686f583-bf38-4655-b277-c15b40bc031a 1
201608250041 0686f583-bf38-4655-b277-c15b40bc031a 1
all 0686f583-bf38-4655-b277-c15b40bc031a 2
all all 5
201605270017 all 1
201605270027 all 1
201607190004 all 1
201608250041 all 1
201609200030 all 1

3、group by roolup

group by roolup(字段1,字段2) 或者 group by (字段1,字段2) with roolup

ROLLUP会根据GROUP BY后面的字段从右到左逐步以去掉右边一个字段,逐步向上累计求和。

举例:

SELECT
CASE grouping(ID)
WHEN 1 THEN 'all'
ELSE ID END AS ID,
CASE grouping(CODE)
WHEN 1 THEN 'all'
ELSE CODE END AS CODE,
count(*) AS '合计'
FROM LeaveApply
GROUP BY rollup(ID,CODE)
-----having可以过滤数据
分组:(ID,CODE),(ID),()

CODE ID 合计
varchar(36) varchar(36) int
0160135e-b693-4a42-b62b-506dd0d9fda5 201605270017 1
0160135e-b693-4a42-b62b-506dd0d9fda5 201605270027 1
0160135e-b693-4a42-b62b-506dd0d9fda5 all 2
02338f05-1b8c-4cfb-9493-dae4c8434977 201609200030 1
02338f05-1b8c-4cfb-9493-dae4c8434977 all 1
0686f583-bf38-4655-b277-c15b40bc031a 201607190004 1
0686f583-bf38-4655-b277-c15b40bc031a 201608250041 1
0686f583-bf38-4655-b277-c15b40bc031a all 2
all all 5