mysql group by cube_SQL Server 之 GROUP BY、GROUPING SETS、ROLLUP、CUBE
发布日期:2021-06-24 17:54:26 浏览次数:2 分类:技术文章

本文共 4040 字,大约阅读时间需要 13 分钟。

1.创建表 Staff

CREATE TABLE [dbo].[Staff]([ID] [int] IDENTITY(1,1) NOT NULL,[Name] [varchar](50) NULL,[Sex] [varchar](50) NULL,[Department] [varchar](50) NULL,[Money] [int] NULL,[CreateDate] [datetime] NULL)ON [PRIMARY]

GO

2.为Staff表填充数据

INSERT INTO [dbo].[Staff]([Name],[Sex],[Department],[Money],[CreateDate])SELECT 'Name1','男','技术部',3000,'2011-11-12'

UNION ALL

SELECT 'Name2','男','工程部',4000,'2013-11-12'

UNION ALL

SELECT 'Name3','女','工程部',3000,'2013-11-12'

UNION ALL

SELECT 'Name4','女','技术部',5000,'2012-11-12'

UNION ALL

SELECT 'Name5','女','技术部',6000,'2011-11-12'

UNION ALL

SELECT 'Name6','女','技术部',4000,'2013-11-12'

UNION ALL

SELECT 'Name7','女','技术部',5000,'2012-11-12'

UNION ALL

SELECT 'Name8','男','工程部',3000,'2012-11-12'

UNION ALL

SELECT 'Name9','男','工程部',6000,'2011-11-12'

UNION ALL

SELECT 'Name10','男','工程部',3000,'2011-11-12'

UNION ALL

SELECT 'Name11','男','技术部',3000,'2011-11-12'

GROUP BY 分组查询, 一般和聚合函数配合使用

SELECT [DEPARTMENT],SEX, COUNT(1)FROM DBO.[STAFF]

GROUP BY SEX, [DEPARTMENT]

该段SQL是用于查询   某个部门下的男女员工数量 其数据结果如下

10d67425a8239bb94bed4c6948d8952b.png

21e5ae464e20479407597be8685790f8.png

d80df0b30e52fac87c0c83b3fb044251.png

开销比较大

GROUPING SETS

使用 GROUPING SETS 的 GROUP BY 子句可以生成一个等效于由多个简单 GROUP BY 子句的 UNION ALL 生成的结果集,并且其效率比 GROUP BY 要高,SQL Server 2008引入。

1.使用GROUP BY 子句的 UNION ALL 来统计 Staff 表中的性别、部门、薪资、入职年份

SET STATISTICS IO ON

SET STATISTICS TIME ON

SELECT N'总人数' ,'',COUNT(0) FROM [DBO].[STAFF]

UNION ALL

SELECT N'按性别划分', SEX,COUNT(0) FROM [DBO].[STAFF] GROUP BYSEXUNION ALL

SELECT N'按部门统计',[DEPARTMENT],COUNT(0) FROM [DBO].[STAFF] GROUP BY [DEPARTMENT]

UNION ALL

SELECT N'按薪资统计',CONVERT(VARCHAR(10),[MONEY]),COUNT(0) FROM [DBO].[STAFF] GROUP BY [MONEY]

UNION ALL

SELECT N'按入职年份',CONVERT(VARCHAR(10),YEAR([CREATEDATE])),COUNT(0) FROM [DBO].[STAFF] GROUP BY YEAR([CREATEDATE])

4c1b2dfc68bc287196c13eda14081f1f.png

6cbf2d025f5e3826c5215e1a7811a475.png

cbaad7c9cf865c7afd8a555f02d72301.png

2.换成GROUPING SETS的写法

SET STATISTICS IO ON

SET STATISTICS TIME ON

GO

SELECT (CASE

WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=15 THEN N'总人数'

WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=7 THEN N'按性别划分'

WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=11 THEN N'按部门统计'

WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=13 THEN N'按薪资统计'

WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=14 THEN N'按入职年份'

END),

(CASE

WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=15 THEN ''

WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=7 THENSEXWHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=11 THEN [DEPARTMENT]

WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=13 THEN CONVERT(VARCHAR(10),[MONEY])WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=14 THEN CONVERT(VARCHAR(10),YEAR([CREATEDATE]))END)

,COUNT(1)FROM DBO.[STAFF]

GROUP BY GROUPING SETS (SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]),())

7034f5ba181e4f3ac81ca2fb42c96100.png

b876ef476324f5060dd3e450469503c7.png

6f5978da5be2dad7d157641cde16deb2.png

从上述结果中可以看出,采用UNION ALL 是多次扫描表,并将扫描后的查询结果进行组合操作,会增加IO开销,减少CPU和内存开销。

采用GROUPING SETS 是一次性读取所有数据,并在内存中进行聚合操作生成结果,减少IO开销,对CPU和内存消耗增加。但GROUPING SETS 在多列分组时,其性能会比group by高。

这里扫描四次是因为我 GROUP BY GROUPING SETS (SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]),()) 了四列

ROLLUP与CUBE

ROLLUP与CUBE  按一定的规则产生多种分组,然后按各种分组统计数据

ROLLUP与CUBE 区别:

CUBE 会对所有的分组字段进行统计,然后合计。

ROLLUP 按照分组顺序,对第一个字段进行组内统计,最后给出合计。

下面看我查询

SELECT

CASE WHEN (GROUPING(SEX) = 1) THEN '统计-ROLLUP'

ELSE ISNULL(SEX, 'UNKNOWN')END ASSEX ,COUNT(0)FROM DBO.[STAFF]

GROUP BY SEX WITHROLLUPSELECT

CASE WHEN (GROUPING(SEX) = 1) THEN '统计-CUBE'

ELSE ISNULL(SEX, 'UNKNOWN')END ASSEX ,COUNT(0)FROM DBO.[STAFF]

GROUP BY SEX WITH CUBE

f64551c0b9e95421b9086ecc2329bf63.png

看不出差别,我们再加一列

SELECT

CASE WHEN (GROUPING(SEX) = 1) THEN '统计-ROLLUP'

ELSE ISNULL(SEX, 'UNKNOWN')END ASSEX ,CASE WHEN (GROUPING([DEPARTMENT]) = 1) THEN '统计-ROLLUP'

ELSE ISNULL([DEPARTMENT], 'UNKNOWN')END AS [DEPARTMENT],COUNT(0)FROM DBO.[STAFF]

GROUP BY SEX,[DEPARTMENT] WITHROLLUPSELECT

CASE WHEN (GROUPING(SEX) = 1) THEN '统计-CUBE'

ELSE ISNULL(SEX, 'UNKNOWN')END ASSEX ,CASE WHEN (GROUPING([DEPARTMENT]) = 1) THEN '统计-CUBE'

ELSE ISNULL([DEPARTMENT], 'UNKNOWN')END AS [DEPARTMENT],COUNT(0)FROM DBO.[STAFF]

GROUP BY SEX,[DEPARTMENT] WITH CUBE

90688c11e23a1f51a6914533398e5a90.png

可以看出 使用 ROLLUP 会先统计分组下的,然后在对GROUP BY的第一列字段进行统计,最后计算总数,而 CUBE 则是先分组统计,然后统计GRUOP BY 的每个字段,最后进行汇总。

http://www.cnblogs.com/woxpp/p/4688715.html

转载地址:https://blog.csdn.net/weixin_34237125/article/details/113264784 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:mysql mgr 5.6_mysql MGR高可用配置
下一篇:jmeter mysql driver_jmeter测试mysql数据库之JDBC请求

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年04月17日 13时49分14秒