在我们制作报表的时候常常需要分组聚合、多组聚合和总合。如果通过另外的T-SQL语句来聚合难免性能太差。如果通过报表工具的聚合功能虽说比使用额外的T-SQL语句性能上要好很多,不过不够干脆,还是需要先生成整个结果集然后再聚合,而且最最重要的时很多情况下报表的聚合功能可能没办法达到我们需要的效果。GROUPING SETS, CUBE, ROLLUP, GROUPING, GROUPING_ID这几个聚合函数的作用就是在原始语句的基础上完成很多像财务报表需要的聚合功能。

GROUPING SETS相当于把多个GROUP BY语句通过UNION ALL

WITH T AS (
SELECT 'A' A, 'A' B UNION ALL
SELECT 'A' A, 'B' B UNION ALL
SELECT 'A' A, 'C' B UNION ALL
SELECT 'B' A, 'A' B UNION ALL
SELECT 'B' A, 'B' B UNION ALL
SELECT 'B' A, 'C' B UNION ALL
SELECT 'C' A, 'A' B UNION ALL
SELECT 'C' A, 'B' B UNION ALL
SELECT 'C' A, 'C' B) SELECT A, B,
COUNT(A) AS CNT,
GROUPING_ID(A,B)
FROM T
GROUP BY GROUPING SETS(A, B, ());

上面代码输出的结果

通常GROUPING SETS会配合GROUPING_ID或GROUPING函数来完成列的输出,比如聚合列的标签内容。

GROUPING_ID (a, b, c)  = GROUPING(a) + GROUPING(b) + GROUPING(c)

GROUPING 用于区分标准空值和由 ROLLUP、CUBE 或 GROUPING SETS 返回的空值。 作为 ROLLUP、CUBE 或 GROUPING SETS 操作结果返回的 NULL 是 NULL 的特殊应用。 它在结果集内作为列的占位符,表示全体。其实意思就是如果列输出为NULL说明是聚合列,不为空就不是聚合列。一开始很难理解。

SELECT
T.[Group]
,T.CountryRegionCode
,S.Name AS N'Store'
,(SELECT P.FirstName + ' ' + P.LastName
FROM Person.Person AS P
WHERE P.BusinessEntityID = H.SalesPersonID)
AS N'Sales Person'
,SUM(TotalDue)AS N'TotalSold'
,CAST(GROUPING(T.[Group])AS char(1)) +
CAST(GROUPING(T.CountryRegionCode)AS char(1)) +
CAST(GROUPING(S.Name)AS char(1)) +
CAST(GROUPING(H.SalesPersonID)AS char(1))
AS N'GROUPING base-2'
,GROUPING_ID((T.[Group])
,(T.CountryRegionCode),(S.Name),(H.SalesPersonID)
) AS N'GROUPING_ID'
,CASE
WHEN GROUPING_ID(
(T.[Group]),(T.CountryRegionCode)
,(S.Name),(H.SalesPersonID)
) = 15 THEN N'Grand Total'
WHEN GROUPING_ID(
(T.[Group]),(T.CountryRegionCode)
,(S.Name),(H.SalesPersonID)
) = 14 THEN N'SalesPerson Total'
WHEN GROUPING_ID(
(T.[Group]),(T.CountryRegionCode)
,(S.Name),(H.SalesPersonID)
) = 13 THEN N'Store Total'
WHEN GROUPING_ID(
(T.[Group]),(T.CountryRegionCode)
,(S.Name),(H.SalesPersonID)
) = 12 THEN N'Store SalesPerson Total'
WHEN GROUPING_ID(
(T.[Group]),(T.CountryRegionCode)
,(S.Name),(H.SalesPersonID)
) = 11 THEN N'CountryRegionCode Total'
WHEN GROUPING_ID(
(T.[Group]),(T.CountryRegionCode)
,(S.Name),(H.SalesPersonID)
) = 7 THEN N'Group Total'
ELSE N'Error'
END AS N'Level'
FROM Sales.Customer AS C
INNER JOIN Sales.Store AS S
ON C.StoreID = S.BusinessEntityID
INNER JOIN Sales.SalesTerritory AS T
ON C.TerritoryID = T.TerritoryID
INNER JOIN Sales.SalesOrderHeader AS H
ON C.CustomerID = H.CustomerID
GROUP BY GROUPING SETS ((S.Name,H.SalesPersonID)
,(H.SalesPersonID),(S.Name)
,(T.[Group]),(T.CountryRegionCode),()
)
--HAVING GROUPING_ID(
-- (T.[Group]),(T.CountryRegionCode),(S.Name),(H.SalesPersonID)
-- ) = @GroupingLevel
ORDER BY
GROUPING_ID(S.Name,H.SalesPersonID),GROUPING_ID((T.[Group])
,(T.CountryRegionCode)
,(S.Name)
,(H.SalesPersonID))ASC;

上面代码来自MSDN的例子,数据库是示例数据库--AdventureWork2012

在只有一列作为GROUP BY CUBE/ROLLUP的列的情况下,两个函数是一样的效果。

CUBE和ROLLUP的区别就是CUBE比ROLLUP多输出多列的情况下,CUBE比ROLLUP多做的事情就是针对后面列的单独聚合行输出。

WITH T AS (
SELECT 'A' A, 'A' B UNION ALL
SELECT 'A' A, 'B' B UNION ALL
SELECT 'A' A, 'C' B UNION ALL
SELECT 'B' A, 'A' B UNION ALL
SELECT 'B' A, 'B' B UNION ALL
SELECT 'B' A, 'C' B UNION ALL
SELECT 'C' A, 'A' B UNION ALL
SELECT 'C' A, 'B' B UNION ALL
SELECT 'C' A, 'C' B) SELECT A, B,
COUNT(A) AS CNT,
GROUPING_ID(A,B)
FROM T
GROUP BY CUBE(A, B); WITH T AS (
SELECT 'A' A, 'A' B UNION ALL
SELECT 'A' A, 'B' B UNION ALL
SELECT 'A' A, 'C' B UNION ALL
SELECT 'B' A, 'A' B UNION ALL
SELECT 'B' A, 'B' B UNION ALL
SELECT 'B' A, 'C' B UNION ALL
SELECT 'C' A, 'A' B UNION ALL
SELECT 'C' A, 'B' B UNION ALL
SELECT 'C' A, 'C' B) SELECT A, B,
COUNT(A) AS CNT,
GROUPING_ID(A,B)
FROM T
GROUP BY ROLLUP(A, B);

SQL Server ->> GROUPING SETS, CUBE, ROLLUP, GROUPING, GROUPING_ID的更多相关文章

  1. grouping sets,cube,rollup,grouping__id,group by

    例1: hive -e" select type ,status ,count(1) from usr_info where pt='2015-09-14' group by type,st ...

  2. 转:GROUPING SETS、ROLLUP、CUBE

    转:http://blog.csdn.net/shangboerds/article/details/5193211 大家对GROUP BY应该比较熟悉,如果你感觉自己并不完全理解GROUP BY,那 ...

  3. GROUPING SETS、ROLLUP、CUBE

    大家对GROUP BY应该比较熟悉,如果你感觉自己并不完全理解GROUP BY,那么本文不适合你.还记得当初学习SQL的时候,总是理解不了GROUP BY的作用,经过好长时间才终于明白GROUP BY ...

  4. SQL Server 之 GROUP BY、GROUPING SETS、ROLLUP、CUBE

    1.创建表 Staff CREATE TABLE [dbo].[Staff]( ,) NOT NULL, ) NULL, ) NULL, ) NULL, [Money] [int] NULL, [Cr ...

  5. SQL Server关于WITH CUBE、WITH ROLLUP和GROUPING使用

    通过查看sql 2005的帮助文档找到了CUBE 和 ROLLUP 之间的具体区别:CUBE 生成的结果集显示了所选列中值的所有组合的聚合.ROLLUP 生成的结果集显示了所选列中值的某一层次结构的聚 ...

  6. Grouping Sets:CUBE和ROLLUP从句

    在上一篇文章里我讨论了SQL Server里Grouping Sets的功能.从文中的例子可以看到,通过简单定义需要的分组集是很容易进行各自分组.但如果像从所给的列集里想要有所有可能的分布——即所谓的 ...

  7. group by <grouping sets(...) ><cube(...)>

    GROUP BY      GROUPING SETS() 后面将还会写学习 with cube,  with rollup,以及将它们转换为标准的GROUP BY的子句GROUP SET(), CU ...

  8. Group By 多个分组集小结 --GROUPING SETS,GROUP BY CUBE,GROUP BY ROLLUP,GROUPING(),GROUPING_ID()

    T-SQL 多个分组集共有三种 GROUPING SETS, CUBE, 以及ROLLUP, 其中 CUBE和ROLLUP可以当做是GROUPING SETS的简写版 示例数据库下载: http:// ...

  9. SQL Server里Grouping Sets的威力

    在SQL Server里,你有没有想进行跨越多个列/纬度的聚集操作,不使用SSAS许可(SQL Server分析服务).我不是说在生产里使用开发版,也不是说安装盗版SQL Server. 不可能的任务 ...

随机推荐

  1. 华农js抢课神器

    又到了华农选课的时候,服务器估计就受不了,每天奔溃几次,这次选课贪心了点,竟然选了5门,好吧,我承认我只中了1门,什么??刚刚换课给同学马上就被人抢了?我来告诉你原因吧,最近发现一位大神写了一份js脚 ...

  2. Sencha Touch xtype对应的class

    Sencha Touch 2的有效xtype xtype Class ----------------- --------------------- actionsheet Ext.ActionShe ...

  3. ios 环境配置网址

    http://blog.csdn.net/cwb1128/article/details/18019751

  4. JS数据类型的理解(猜测)

    Js 数据类型 对于这个主题,首先来看几个问题,如果你对这几个问题很清楚的话,那就请直接跳过吧,不用接着往下看了,如果不清楚,建议你还是看看. 1)如果判断函数?function 和object的联系 ...

  5. 在iptables防火墙下开启vsftpd的端口

    在开启vsftpd端口后发现用客户端工具能登陆,但无法浏览文件和新建文件.此时看了一下ftp的协议,发现ftp有主动模式和被动模式.在服务端开21端口是让客户端进来,并没有出去的端口,还在服务端开启出 ...

  6. 充分发挥异步在 ASP.NET 中的强大优势

    作者:Brij Bhushan Mishra 最近几年,异步编程受到极大关注,主要是出于两个关键原因:首先,它有助于提供更好的用户体验,因为不会阻塞 UI 线程,避免了处理结束前出现 UI 界面挂起. ...

  7. 用VBS将PPT转为图片

    '使用方法:把ppt文件拖放到该文件上. '机器上要安装Powerpoint程序 On Error Resume Next Set ArgObj = WScript.Arguments pptfile ...

  8. post 方式提交XML文件调用接口

    import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.Date; import java. ...

  9. Codeforces 294B Shaass and Bookshelf(记忆化搜索)

    题目 记忆化搜索(深搜+记录状态) 感谢JLGG //记忆话搜索 //一本书2中状态,竖着放或者横着放 //初始先都竖着放,然后从左边往右边扫 #include<stdio.h> #inc ...

  10. BroadcastReceiver应用1

    有两种注册方式:1. 在AndroidManifest中注册.2. 在代码中直接注册,这种注册需要注意的一点是:当注册此Receiver的Activity退出的时候,一定要调用unregisterRe ...