在我们制作报表的时候常常需要分组聚合、多组聚合和总合。如果通过另外的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. linux查看文件权限

    ls -l abc (abc是文件名) 那么就会出现相类似的信息,主要都是这些:drwxr-xr-x 一共有10位数 其中: 最前面那个 d 代表的是类型 目录文件 中间那三个 rw- 代表的是所有者 ...

  2. 20145120 《Java程序设计》第7周学习总结

    20145120 <Java程序设计>第7周学习总结 教材学习内容总结 Lambda表达式 例:Comparator<String> byLength = (name1, na ...

  3. “我爱淘”冲刺阶段Scrum站立会议8

    完成任务: 今天最大的成功就是解决了昨天的问题,可以将xml文件的内容解析出来显示到软件中. 计划任务: 可以通过webservice将数据库中的内容解析出来,通过查询可以得到想要的内容. 遇到问题: ...

  4. 增强学习贪心算法与Softmax算法

    (一) 这个算法是基于一个概率来对探索和利用进行折中:每次尝试时,以概率进行探索,即以均匀概率随机选取一个摇臂,以的概率进行利用,即以这个概率选择当前平均奖赏最高的摇臂(如有多个,则随机选取). 其中 ...

  5. php使用循环创建任意长度数组

    实例:生成长度为5的偶数集合 <?php /** * [crtArr description] * @param [int] $start [循环开始变量] * @param [int] $le ...

  6. 【CentOS】设置静态IP

      问题描述:         CentOS配置静态IP   问题解决:         (1)修改IP--修改配置文件/etc/sysconfig/network-scripts/ifcfg-eth ...

  7. Winform DataGridView扩展

    public class ObjectPropertyCompare<T> : IComparer<T> { private readonly PropertyDescript ...

  8. NYOJ-85 有趣的数 AC 分类: NYOJ 2014-01-17 21:42 240人阅读 评论(0) 收藏

    这道题目就是,找规律,小学奥数,找规律不难吧, #include<stdio.h> int sc(int x); int main(){ int n=0; int num,cs,k; sc ...

  9. linux install

    http://www.ubuntu.org.cn/index_kylin 先在官网下个Ubuntu  是个iso 然后下个UltraISO 是个软件 插好空u盘 打开软件 在菜单栏上 点击 文件-&g ...

  10. Python中的正则表达式regular expression

    1 match = re.search(pat,str)  If the search is successful, search() returns a match object or None o ...