在我们制作报表的时候常常需要分组聚合、多组聚合和总合。如果通过另外的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. 怎么将java项目打包成双击就可以运行的jar包---fatjar

    fatjar下载地址:http://pan.baidu.com/s/1cQ01o 下载fatJar插件,解压缩后是一个.../plugins/(net...)把plugins下面的(net..)文件夹 ...

  2. Careercup - Google面试题 - 5661939564806144

    2014-05-06 01:40 题目链接 原题: Give a N*N matrix, print it out diagonally. Follow up, if it is a M*N matr ...

  3. 【Minimum Depth of Binary Tree】cpp

    题目: Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along the ...

  4. 读书笔记:<我是一只IT小小鸟>

    <我是一只IT小小鸟>第一次听到这本书的时候,我便有了深深的好奇,虽然我是一名学习软件工程的大学生,但是还是第一次听到“IT”这个名词,既陌生又好奇.听到老师提起了这本书的意义以及看法,我 ...

  5. Codeforces Round #254 (Div. 1) C. DZY Loves Colors 线段树

    题目链接: http://codeforces.com/problemset/problem/444/C J. DZY Loves Colors time limit per test:2 secon ...

  6. eclipse 中卸载插件的方法

    卸载步骤: Help -> About Eclipse -> Installation Details -> "点到你要删除的插件,如EclipseME" –&g ...

  7. 一个关于ExtJS4具体控件的详细教程

    发现一遍介绍ExtJS控件介绍的比较好的系列文章,在此做总结 ExtJs4 笔记(1) ExtJs大比拼JQuery:Dom文档操作 ExtJs4 笔记(2) ExtJs对js基本语法扩展支持 Ext ...

  8. thinkPHP生成静态分页列表

    改造分页类Pagehtml.class.php <?php // 静态分页列表类 class Pagehtml extends Think { //分页url public $pageUrl; ...

  9. [百度空间] [转]DLL地狱及其解决方案

    DLL地狱及其解决方案 原作者:Ivan S Zapreev 译者:陆其明概要 本文将要介绍DLL的向后兼容性问题,也就是著名的“DLL Hell”问题.首先我会列出自己的研究结果,其中包括其它一些研 ...

  10. Java正则表达式匹配例子

    Java正则表达式匹配例子 package com.ibm.test; import java.util.regex.Matcher; import java.util.regex.Pattern; ...