SQL学习笔记:将 GROUP BY 与 ROLLUP、CUBE 和 GROUPING SETS 一起使用
ROLLUP、CUBE 和 GROUPING SETS 运算符是 GROUP BY 子句的扩展。ROLLUP、CUBE 或 GROUPING SETS 运算符可以生成与使用 UNION ALL 来组合单个分组查询时相同的结果集;但是,使用其中一种 GROUP BY 运算符通常更有效。
GROUPING SETS 运算符可以生成与使用单个 GROUP BY、ROLLUP 或 CUBE 运算符所生成的结果集相同的结果集。如果不需要获得由完备的 ROLLUP 或 CUBE 运算符生成的全部分组,则可以使用 GROUPING SETS 仅指定所需的分组。GROUPING SETS 列表可以包含重复的分组;当 GROUPING SETS 与 ROLLUP 和 CUBE 一起使用时,它就可能会生成重复的分组。使用 UNION ALL 可以原样保留重复的分组。
注意: |
---|
CUBE、ROLLUP 和 GROUPING SETS 不支持 CHECKSUM_AGG 函数。 |
组合元素和串联元素
位于 GROUPING SETS 列表内部括号中的多个列被视为一个集。例如,在子句 GROUP BY GROUPING SETS ((Colum1, Column2), Column3, Column4)
中,Column1
和 Column2
被视为一个列。有关如何使用带有组合元素的 GROUPING SETS 的示例,请参阅本主题后面的示例 H。
当 GROUPING SETS 列表在内部括号中包含由逗号分隔的多个集时,集的输出将串联在一起。结果集是分组集的叉积或笛卡尔积。有关如何将 GROUP BY 与串联 ROLLUP 操作一起使用的示例,请参阅本主题后面的示例 D。
ROLLUP 和 CUBE 与 OLAP 维度的比较
使用 ROLLUP 和 CUBE 运算符的查询会生成某些与 OLAP 应用程序生成的结果集相同的结果集,并会执行某些与 OLAP 应用程序执行的计算相同的计算。CUBE 运算符生成的结果集可用于交叉表格报表。ROLLUP 操作可以计算 OLAP 维度或层次结构的等效项。
例如,假设一个时间维度具有年、月和日级别或属性,以下 ROLLUP
操作将生成下列分组。
操作 | 分组 | ||||
---|---|---|---|---|---|
|
|
假设一个位置维度具有地区和城市级别并串联了时间维度级别年、月和日,以下 ROLLUP
操作将输出下列分组。
操作 | 分组 | ||||
---|---|---|---|---|---|
|
|
具有相同位置和时间维度级别的 CUBE
操作将输出下列分组。
操作 | 分组 | ||||
---|---|---|---|---|---|
|
|
结果集中的 NULL
在 GROUP BY 运算符生成的结果集中,NULL 具有以下用法:
- 如果分组依据列包含 NULL,则所有空值将被视为是相等的,并会将其放入一个 NULL 组中。
- 将一列聚合为一行时,该列的值显示为 NULL。
下例使用 GROUPING
函数演示 NULL 的这两种用法。在已将其列中的空值分组的行中,UNKNOWN
将替换 NULL
。在 NULL
表明列已包括在聚合中的列中,ALL
将替换 NULL
。
USE tempdb; GO CREATE TABLE dbo.GroupingNULLS ( Store nvarchar(19) ,SaleYear nvarchar(4) ,SaleMonth nvarchar (7)) INSERT INTO dbo.GroupingNULLS VALUES( NULL,NULL,'January') INSERT INTO dbo.GroupingNULLS VALUES( NULL,'2002',NULL) INSERT INTO dbo.GroupingNULLS VALUES( NULL,NULL,NULL) INSERT INTO dbo.GroupingNULLS VALUES( 'Active Cycling',NULL ,'January'); INSERT INTO dbo.GroupingNULLS VALUES( 'Active Cycling','2002',NULL); INSERT INTO dbo.GroupingNULLS VALUES( 'Active Cycling',NULL ,NULL;) INSERT INTO dbo.GroupingNULLS VALUES( 'Active Cycling',NULL,'January'); INSERT INTO dbo.GroupingNULLS VALUES( 'Active Cycling','2003','Febuary'); INSERT INTO dbo.GroupingNULLS VALUES( 'Active Cycling','2003',NULL); INSERT INTO dbo.GroupingNULLS VALUES( 'Mountain Bike Store','2002','January'); INSERT INTO dbo.GroupingNULLS VALUES( 'Mountain Bike Store','2002',NULL); INSERT INTO dbo.GroupingNULLS VALUES( 'Mountain Bike Store',NULL,NULL); INSERT INTO dbo.GroupingNULLS VALUES( 'Mountain Bike Store','2003','January'); INSERT INTO dbo.GroupingNULLS VALUES( 'Mountain Bike Store','2003','Febuary'); INSERT INTO dbo.GroupingNULLS VALUES( 'Mountain Bike Store','2003','March'); SELECT ISNULL(Store, CASE WHEN GROUPING(Store) = 0 THEN 'UNKNOWN' ELSE 'ALL' END) AS Store ,ISNULL(CAST(SaleYear AS nvarchar(7)), CASE WHEN GROUPING(SaleYear)= 0 THEN 'UNKNOWN' ELSE 'ALL' END) AS SalesYear ,ISNULL(SaleMonth, CASE WHEN GROUPING(SaleMonth) = 0 THEN 'UNKNOWN' ELSE 'ALL'END) AS SalesMonth ,COUNT(*) AS Count FROM dbo.GroupingNULLS GROUP BY ROLLUP(Store, SaleYear, SaleMonth); |
下面是结果集:
Store | SalesYear | SalesMonth | Count |
---|---|---|---|
Unknown |
Unknown |
Unknown |
1 |
Unknown |
Unknown |
January |
1 |
Unknown |
Unknown |
ALL |
2 |
Unknown |
2002 |
Unknown |
1 |
Unknown |
2002 |
ALL |
1 |
Unknown |
ALL |
ALL |
3 |
Active Cycling |
Unknown |
Unknown |
1 |
Active Cycling |
Unknown |
January |
2 |
Active Cycling |
Unknown |
ALL |
3 |
Active Cycling |
2002 |
Unknown |
1 |
Active Cycling |
2002 |
ALL |
1 |
Active Cycling |
2003 |
Unknown |
1 |
Active Cycling |
2003 |
Febuary |
1 |
Active Cycling |
2003 |
ALL |
2 |
Active Cycling |
ALL |
ALL |
6 |
Mountain Bike Store |
Unknown |
Unknown |
1 |
Mountain Bike Store |
Unknown |
ALL |
1 |
Mountain Bike Store |
2002 |
Unknown |
1 |
Mountain Bike Store |
2002 |
January |
1 |
Mountain Bike Store |
2002 |
ALL |
2 |
Mountain Bike Store |
2003 |
Febuary |
1 |
Mountain Bike Store |
2003 |
January |
1 |
Mountain Bike Store |
2003 |
March |
1 |
Mountain Bike Store |
2003 |
ALL |
3 |
Mountain Bike Store |
ALL |
ALL |
6 |
ALL |
ALL |
ALL |
15 |
示例
本部分中的示例使用 SUM 聚合函数以便可以比较结果集。还可以使用其他聚合函数来计算不同的汇总值。
A. 使用简单 GROUP BY
在下例中,简单 GROUP BY
将返回一个结果集以便与示例 B 到 K 的结果集进行比较。这些示例使用 GROUP BY
运算符和相同的 SELECT
语句。
USE AdventureWorks; GO SELECT T.[Group] AS N'Region', T.CountryRegionCode AS N'Country' ,S.Name AS N'Store', H.SalesPersonID ,SUM(TotalDue) AS N'Total Sales' FROM Sales.Customer C INNER JOIN Sales.Store S ON C.CustomerID = S.CustomerID INNER JOIN Sales.SalesTerritory T ON C.TerritoryID = T.TerritoryID INNER JOIN Sales.SalesOrderHeader H ON S.CustomerID = H.CustomerID WHERE T.[Group] = N'Europe' AND T.CountryRegionCode IN(N'DE', N'FR') AND H.SalesPersonID IN(284, 286, 289) AND SUBSTRING(S.Name,1,4)IN(N'Vers', N'Spa ') GROUP BY T.[Group], T.CountryRegionCode, S.Name, H.SalesPersonID ORDER BY T.[Group], T.CountryRegionCode ,S.Name,H.SalesPersonID; |
下面是结果集:
Region | Country | Store | SalesPersonID | Total Sales |
---|---|---|---|---|
Europe |
DE |
Versatile Sporting Goods Company |
284 |
859.232 |
Europe |
DE |
Versatile Sporting Goods Company |
289 |
17691.83 |
Europe |
FR |
Spa and Exercise Outfitters |
284 |
32774.36 |
Europe |
FR |
Spa and Exercise Outfitters |
286 |
246272.4 |
B. 使用 GROUP BY ROLLUP
在下例中,ROLLUP
运算符返回一个包含以下分组的结果集:
Region
、Country
、Store
和SalesPersonID
Region
、Country
和Store
Region
和Country
Region
- 总计
ROLLUP
生成的分组数等于 ROLLUP
列表中的列数加上总计分组数。分组中的行数由分组的列中的值的唯一组合数确定。
USE AdventureWorks; GO SELECT T.[Group] AS N'Region', T.CountryRegionCode AS N'Country' ,S.Name AS N'Store', H.SalesPersonID ,SUM(TotalDue) AS N'Total Sales' FROM Sales.Customer C INNER JOIN Sales.Store S ON C.CustomerID = S.CustomerID INNER JOIN Sales.SalesTerritory T ON C.TerritoryID = T.TerritoryID INNER JOIN Sales.SalesOrderHeader H ON S.CustomerID = H.CustomerID WHERE T.[Group] = N'Europe' AND T.CountryRegionCode IN(N'DE', N'FR') AND H.SalesPersonID IN(284, 286, 289) AND SUBSTRING(S.Name,1,4)IN(N'Vers', N'Spa ') GROUP BY ROLLUP( T.[Group], T.CountryRegionCode, S.Name, H.SalesPersonID) ORDER BY T.[Group], T.CountryRegionCode, S.Name, H.SalesPersonID; |
下面是结果集:
Region | Country | Store | SalesPersonID | Total Sales |
---|---|---|---|---|
NULL |
NULL |
NULL |
NULL |
297597.8 |
Europe |
NULL |
NULL |
NULL |
297597.8 |
Europe |
DE |
NULL |
NULL |
18551.07 |
Europe |
DE |
Versatile Sporting Goods Company |
NULL |
18551.07 |
Europe |
DE |
Versatile Sporting Goods Company |
284 |
859.232 |
Europe |
DE |
Versatile Sporting Goods Company |
289 |
17691.83 |
Europe |
FR |
NULL |
NULL |
279046.8 |
Europe |
FR |
Spa and Exercise Outfitters |
NULL |
279046.8 |
Europe |
FR |
Spa and Exercise Outfitters |
284 |
32774.36 |
Europe |
FR |
Spa and Exercise Outfitters |
286 |
246272.4 |
C. 在列顺序颠倒的情况下使用 GROUP BY ROLLUP
在下例中,ROLLUP
运算符返回一个包含以下分组的结果集:
SalesPersonID
、Store
、Country
和Region
SalesPersonID
、Store
和Country
SalesPersonID
和Store
SalesPersonID
- 总计
ROLLUP
列表中的列与示例 B 中的那些列相同,但其顺序相反。列从右至左进行汇总,因此,顺序会影响分组。结果集中的行数可能会随列顺序而变化。
USE AdventureWorks; GO SELECT T.[Group] AS N'Region', T.CountryRegionCode AS N'Country' ,S.Name AS N'Store', H.SalesPersonID ,SUM(TotalDue) AS N'Total Sales' FROM Sales.Customer C INNER JOIN Sales.Store S ON C.CustomerID = S.CustomerID INNER JOIN Sales.SalesTerritory T ON C.TerritoryID = T.TerritoryID INNER JOIN Sales.SalesOrderHeader H ON S.CustomerID = H.CustomerID WHERE T.[Group] = N'Europe' AND T.CountryRegionCode IN(N'DE', N'FR') AND H.SalesPersonID IN(284, 286, 289) AND SUBSTRING(S.Name,1,4)IN(N'Vers', N'Spa ') GROUP BY ROLLUP( H.SalesPersonID, S.Name, T.CountryRegionCode, T.[Group]) ORDER BY H.SalesPersonID, S.Name, T.CountryRegionCode, T.[Group]; |
下面是结果集:
Region | Country | Store | SalesPersonID | Total Sales |
---|---|---|---|---|
NULL |
NULL |
NULL |
NULL |
297597.8 |
NULL |
NULL |
NULL |
284 |
33633.59 |
NULL |
NULL |
Spa and Exercise Outfitters |
284 |
32774.36 |
NULL |
FR |
Spa and Exercise Outfitters |
284 |
32774.36 |
Europe |
FR |
Spa and Exercise Outfitters |
284 |
32774.36 |
NULL |
NULL |
Versatile Sporting Goods Company |
284 |
859.232 |
NULL |
DE |
Versatile Sporting Goods Company |
284 |
859.232 |
Europe |
DE |
Versatile Sporting Goods Company |
284 |
859.232 |
NULL |
NULL |
NULL |
286 |
246272.4 |
NULL |
NULL |
Spa and Exercise Outfitters |
286 |
246272.4 |
NULL |
FR |
Spa and Exercise Outfitters |
286 |
246272.4 |
Europe |
FR |
Spa and Exercise Outfitters |
286 |
246272.4 |
NULL |
NULL |
NULL |
289 |
17691.83 |
NULL |
NULL |
Versatile Sporting Goods Company |
289 |
17691.83 |
NULL |
DE |
Versatile Sporting Goods Company |
289 |
17691.83 |
Europe |
DE |
Versatile Sporting Goods Company |
289 |
17691.83 |
D. 将 GROUP BY 与串联 ROLLUP 操作一起使用
下例将返回两个 ROLLUP
操作的叉积。
USE AdventureWorks; GO SELECT T.[Group] AS N'Region', T.CountryRegionCode AS N'Country' ,DATEPART(yyyy,OrderDate) AS 'Year' ,DATEPART(mm,OrderDate) AS 'Month' ,SUM(TotalDue) AS N'Total Sales' FROM Sales.Customer C INNER JOIN Sales.Store S ON C.CustomerID = S.CustomerID INNER JOIN Sales.SalesTerritory T ON C.TerritoryID = T.TerritoryID INNER JOIN Sales.SalesOrderHeader H ON S.CustomerID = H.CustomerID WHERE T.[Group] = N'Europe' AND T.CountryRegionCode IN(N'DE', N'FR') AND DATEPART(yyyy,OrderDate) = '2004' GROUP BY ROLLUP(T.[Group], T.CountryRegionCode) ,ROLLUP(DATEPART(yyyy,OrderDate), DATEPART(mm,OrderDate)) ORDER BY T.[Group], T.CountryRegionCode ,DATEPART(yyyy,OrderDate), DATEPART(mm,OrderDate); |
下面是结果集:
Region | Country | Year | Month | Total Sales |
---|---|---|---|---|
NULL |
NULL |
NULL |
NULL |
3031201 |
NULL |
NULL |
2004 |
NULL |
3031201 |
NULL |
NULL |
2004 |
1 |
208553.6 |
NULL |
NULL |
2004 |
2 |
819466.6 |
NULL |
NULL |
2004 |
3 |
298579.1 |
NULL |
NULL |
2004 |
4 |
294427.7 |
NULL |
NULL |
2004 |
5 |
1070679 |
NULL |
NULL |
2004 |
6 |
339495.1 |
Europe |
NULL |
NULL |
NULL |
3031201 |
Europe |
NULL |
2004 |
NULL |
3031201 |
Europe |
NULL |
2004 |
1 |
208553.6 |
Europe |
NULL |
2004 |
2 |
819466.6 |
Europe |
NULL |
2004 |
3 |
298579.1 |
Europe |
NULL |
2004 |
4 |
294427.7 |
Europe |
NULL |
2004 |
5 |
1070679 |
Europe |
NULL |
2004 |
6 |
339495.1 |
Europe |
DE |
NULL |
NULL |
1196260 |
Europe |
DE |
2004 |
NULL |
1196260 |
Europe |
DE |
2004 |
1 |
155066.2 |
Europe |
DE |
2004 |
2 |
197801.8 |
Europe |
DE |
2004 |
3 |
180977.7 |
Europe |
DE |
2004 |
4 |
222683.4 |
Europe |
DE |
2004 |
5 |
258962 |
Europe |
DE |
2004 |
6 |
180769.1 |
Europe |
FR |
NULL |
NULL |
1834941 |
Europe |
FR |
2004 |
NULL |
1834941 |
Europe |
FR |
2004 |
1 |
53487.37 |
Europe |
FR |
2004 |
2 |
621664.9 |
Europe |
FR |
2004 |
3 |
117601.4 |
Europe |
FR |
2004 |
4 |
71744.28 |
Europe |
FR |
2004 |
5 |
811716.9 |
Europe |
FR |
2004 |
6 |
158726 |
E. 使用 GROUP BY CUBE
在下例中,CUBE
运算符返回的结果集具有一个针对 CUBE
列表和总计分组中的列的所有可能组合的分组。
USE AdventureWorks; GO SELECT T.[Group] AS N'Region', T.CountryRegionCode AS N'Country' ,S.Name AS N'Store', H.SalesPersonID ,SUM(TotalDue) AS N'Total Sales' FROM Sales.Customer C INNER JOIN Sales.Store S ON C.CustomerID = S.CustomerID INNER JOIN Sales.SalesTerritory T ON C.TerritoryID = T.TerritoryID INNER JOIN Sales.SalesOrderHeader H ON S.CustomerID = H.CustomerID WHERE T.[Group] = N'Europe' AND T.CountryRegionCode IN(N'DE', N'FR') AND H.SalesPersonID IN(284, 286, 289) AND SUBSTRING(S.Name,1,4)IN(N'Vers', N'Spa ') GROUP BY CUBE( T.[Group], T.CountryRegionCode, S.Name, H.SalesPersonID) ORDER BY T.[Group], T.CountryRegionCode, S.Name, H.SalesPersonID; |
下面是结果集:
Region | Country | Store | SalesPersonID | Total Sales |
---|---|---|---|---|
NULL |
NULL |
NULL |
NULL |
297597.8 |
NULL |
NULL |
NULL |
284 |
33633.59 |
NULL |
NULL |
NULL |
286 |
246272.4 |
NULL |
NULL |
NULL |
289 |
17691.83 |
NULL |
NULL |
Spa and Exercise Outfitters |
NULL |
279046.8 |
NULL |
NULL |
Spa and Exercise Outfitters |
284 |
32774.36 |
NULL |
NULL |
Spa and Exercise Outfitters |
286 |
246272.4 |
NULL |
NULL |
Versatile Sporting Goods Company |
NULL |
18551.07 |
NULL |
NULL |
Versatile Sporting Goods Company |
284 |
859.232 |
NULL |
NULL |
Versatile Sporting Goods Company |
289 |
17691.83 |
NULL |
DE |
NULL |
NULL |
18551.07 |
NULL |
DE |
NULL |
284 |
859.232 |
NULL |
DE |
NULL |
289 |
17691.83 |
NULL |
DE |
Versatile Sporting Goods Company |
NULL |
18551.07 |
NULL |
DE |
Versatile Sporting Goods Company |
284 |
859.232 |
NULL |
DE |
Versatile Sporting Goods Company |
289 |
17691.83 |
NULL |
FR |
NULL |
NULL |
279046.8 |
NULL |
FR |
NULL |
284 |
32774.36 |
NULL |
FR |
NULL |
286 |
246272.4 |
NULL |
FR |
Spa and Exercise Outfitters |
NULL |
279046.8 |
NULL |
FR |
Spa and Exercise Outfitters |
284 |
32774.36 |
NULL |
FR |
Spa and Exercise Outfitters |
286 |
246272.4 |
Europe |
NULL |
NULL |
NULL |
297597.8 |
Europe |
NULL |
NULL |
284 |
33633.59 |
Europe |
NULL |
NULL |
286 |
246272.4 |
Europe |
NULL |
NULL |
289 |
17691.83 |
Europe |
NULL |
Spa and Exercise Outfitters |
NULL |
279046.8 |
Europe |
NULL |
Spa and Exercise Outfitters |
284 |
32774.36 |
Europe |
NULL |
Spa and Exercise Outfitters |
286 |
246272.4 |
Europe |
NULL |
Versatile Sporting Goods Company |
NULL |
18551.07 |
Europe |
NULL |
Versatile Sporting Goods Company |
284 |
859.232 |
Europe |
NULL |
Versatile Sporting Goods Company |
289 |
17691.83 |
Europe |
DE |
NULL |
NULL |
18551.07 |
Europe |
DE |
NULL |
284 |
859.232 |
Europe |
DE |
NULL |
289 |
17691.83 |
Europe |
DE |
Versatile Sporting Goods Company |
NULL |
18551.07 |
Europe |
DE |
Versatile Sporting Goods Company |
284 |
859.232 |
Europe |
DE |
Versatile Sporting Goods Company |
289 |
17691.83 |
Europe |
FR |
NULL |
NULL |
279046.8 |
Europe |
FR |
NULL |
284 |
32774.36 |
Europe |
FR |
NULL |
286 |
246272.4 |
Europe |
FR |
Spa and Exercise Outfitters |
NULL |
279046.8 |
Europe |
FR |
Spa and Exercise Outfitters |
284 |
32774.36 |
Europe |
FR |
Spa and Exercise Outfitters |
286 |
246272.4 |
F. 使用 CUBE 与组合元素
在下例中,CUBE
运算符返回的结果集具有一个针对 CUBE
列表和总计分组中的列的所有可能组合的分组。
该运算符将每个分组的列 (T.[Group], T.CountryRegionCode)
和 (DATEPART(yyyy,OrderDate), DATEPART(mm,OrderDate))
作为单个列来处理。
USE AdventureWorks; GO SELECT T.[Group] AS N'Region', T.CountryRegionCode AS N'Country' ,DATEPART(yyyy,OrderDate) AS 'Year' ,DATEPART(mm,OrderDate) AS 'Month' ,SUM(TotalDue) AS N'Total Sales' FROM Sales.Customer C INNER JOIN Sales.Store S ON C.CustomerID = S.CustomerID INNER JOIN Sales.SalesTerritory T ON C.TerritoryID = T.TerritoryID INNER JOIN Sales.SalesOrderHeader H ON S.CustomerID = H.CustomerID WHERE T.[Group] = N'Europe' AND T.CountryRegionCode IN(N'DE', N'FR') AND DATEPART(yyyy,OrderDate) = '2004' GROUP BY CUBE( (T.[Group], T.CountryRegionCode) ,(DATEPART(yyyy,OrderDate), DATEPART(mm,OrderDate))) ORDER BY T.[Group], T.CountryRegionCode ,DATEPART(yyyy,OrderDate), DATEPART(mm,OrderDate); |
下面是结果集:
Region | Country | Year | Month | Total Sales |
---|---|---|---|---|
NULL |
NULL |
NULL |
NULL |
3031201 |
NULL |
NULL |
2004 |
1 |
208553.6 |
NULL |
NULL |
2004 |
2 |
819466.6 |
NULL |
NULL |
2004 |
3 |
298579.1 |
NULL |
NULL |
2004 |
4 |
294427.7 |
NULL |
NULL |
2004 |
5 |
1070679 |
NULL |
NULL |
2004 |
6 |
339495.1 |
Europe |
DE |
NULL |
NULL |
1196260 |
Europe |
DE |
2004 |
1 |
155066.2 |
Europe |
DE |
2004 |
2 |
197801.8 |
Europe |
DE |
2004 |
3 |
180977.7 |
Europe |
DE |
2004 |
4 |
222683.4 |
Europe |
DE |
2004 |
5 |
258962 |
Europe |
DE |
2004 |
6 |
180769.1 |
Europe |
FR |
NULL |
NULL |
1834941 |
Europe |
FR |
2004 |
1 |
53487.37 |
Europe |
FR |
2004 |
2 |
621664.9 |
Europe |
FR |
2004 |
3 |
117601.4 |
Europe |
FR |
2004 |
4 |
71744.28 |
Europe |
FR |
2004 |
5 |
811716.9 |
Europe |
FR |
2004 |
6 |
158726 |
G. 将 GROUP BY 与 GROUPING SETS 一起使用
在下例中,GROUPING SETS
运算符具有四个分组,针对 SELECT
列表中的每列各一个。该运算符为 Region
、Country
、Store
和 SalesPersonID
列中的每个唯一值返回一行。
USE AdventureWorks; GO SELECT T.[Group] AS N'Region', T.CountryRegionCode AS N'Country' ,S.Name AS N'Store', H.SalesPersonID ,SUM(TotalDue) AS N'Total Sales' FROM Sales.Customer C INNER JOIN Sales.Store S ON C.CustomerID = S.CustomerID INNER JOIN Sales.SalesTerritory T ON C.TerritoryID = T.TerritoryID INNER JOIN Sales.SalesOrderHeader H ON S.CustomerID = H.CustomerID WHERE T.[Group] = N'Europe' AND T.CountryRegionCode IN(N'DE', N'FR') AND H.SalesPersonID IN(284, 286, 289) AND SUBSTRING(S.Name,1,4)IN(N'Vers', N'Spa ') GROUP BY GROUPING SETS (T.[Group], T.CountryRegionCode, S.Name, H.SalesPersonID) ORDER BY T.[Group], T.CountryRegionCode, S.Name, H.SalesPersonID; |
下面是结果集:
Region | Country | Store | SalesPersonID | Total Sales |
---|---|---|---|---|
NULL |
NULL |
NULL |
284 |
33633.59 |
NULL |
NULL |
NULL |
286 |
246272.4 |
NULL |
NULL |
NULL |
289 |
17691.83 |
NULL |
NULL |
Spa and Exercise Outfitters |
NULL |
279046.8 |
NULL |
NULL |
Versatile Sporting Goods Company |
NULL |
18551.07 |
NULL |
DE |
NULL |
NULL |
18551.07 |
NULL |
FR |
NULL |
NULL |
279046.8 |
Europe |
NULL |
NULL |
NULL |
297597.8 |
H. 使用 GROUPING SETS 与组合元素
在下例中,GROUPING SETS
列表包含两个组合元素 (T.[Group], T.CountryRegionCode)
和 (DATEPART(yyyy,OrderDate), DATEPART(mm,OrderDate))
。每个组合元素都被视为一列。
USE AdventureWorks; GO SELECT T.[Group] AS N'Region', T.CountryRegionCode AS N'Country' ,DATEPART(yyyy,OrderDate) AS 'Year' ,DATEPART(mm,OrderDate) AS 'Month' ,SUM(TotalDue) AS N'Total Sales' FROM Sales.Customer C INNER JOIN Sales.Store S ON C.CustomerID = S.CustomerID INNER JOIN Sales.SalesTerritory T ON C.TerritoryID = T.TerritoryID INNER JOIN Sales.SalesOrderHeader H ON S.CustomerID = H.CustomerID WHERE T.[Group] = N'Europe' AND T.CountryRegionCode IN(N'DE', N'FR') AND DATEPART(yyyy,OrderDate) = '2004' GROUP BY GROUPING SETS( (T.[Group], T.CountryRegionCode) ,(DATEPART(yyyy,OrderDate), DATEPART(mm,OrderDate))) ORDER BY T.[Group], T.CountryRegionCode ,DATEPART(yyyy,OrderDate), DATEPART(mm,OrderDate); |
下面是结果集:
Region | Country | Year | Month | Total Sales |
---|---|---|---|---|
NULL |
NULL |
2004 |
1 |
208553.6 |
NULL |
NULL |
2004 |
2 |
819466.6 |
NULL |
NULL |
2004 |
3 |
298579.1 |
NULL |
NULL |
2004 |
4 |
294427.7 |
NULL |
NULL |
2004 |
5 |
1070679 |
NULL |
NULL |
2004 |
6 |
339495.1 |
Europe |
DE |
NULL |
NULL |
1196260 |
Europe |
FR |
NULL |
NULL |
1834941 |
I. 将 GROUP BY 与多个 GROUPING SETS 一起使用
在下例中,GROUPING SETS
列表具有五个元素。结果集针对以下元素包含一行:
Region
和Country
列中值的每个唯一组合Store
列中的每个唯一值SalesPersonID
和Region
列中值的每个唯一组合SalesPersonID
列中的每个唯一值- 总计
USE AdventureWorks; GO SELECT T.[Group] AS N'Region', T.CountryRegionCode AS N'Country' ,S.Name AS N'Store', H.SalesPersonID ,SUM(TotalDue) AS N'Total Sales' FROM Sales.Customer C INNER JOIN Sales.Store S ON C.CustomerID = S.CustomerID INNER JOIN Sales.SalesTerritory T ON C.TerritoryID = T.TerritoryID INNER JOIN Sales.SalesOrderHeader H ON S.CustomerID = H.CustomerID WHERE T.[Group] = N'Europe' AND T.CountryRegionCode IN(N'DE', N'FR') AND H.SalesPersonID IN(284, 286, 289) AND SUBSTRING(S.Name,1,4)IN(N'Vers', N'Spa ') GROUP BY GROUPING SETS( (T.[Group], T.CountryRegionCode) ,(S.Name) ,(H.SalesPersonID,T.[Group]) ,(H.SalesPersonID) ,()) ORDER BY T.[Group], T.CountryRegionCode, S.Name, H.SalesPersonID; |
下面是结果集:
Region | Country | Store | SalesPersonID | Total Sales |
---|---|---|---|---|
NULL |
NULL |
NULL |
NULL |
297597.8 |
NULL |
NULL |
NULL |
284 |
33633.59 |
NULL |
NULL |
NULL |
286 |
246272.4 |
NULL |
NULL |
NULL |
289 |
17691.83 |
NULL |
NULL |
Spa and Exercise Outfitters |
NULL |
279046.8 |
NULL |
NULL |
Versatile Sporting Goods Company |
NULL |
18551.07 |
Europe |
NULL |
NULL |
284 |
33633.59 |
Europe |
NULL |
NULL |
286 |
246272.4 |
Europe |
NULL |
NULL |
289 |
17691.83 |
Europe |
DE |
NULL |
NULL |
18551.07 |
Europe |
FR |
NULL |
NULL |
279046.8 |
J. 使用 GROUPING SETS 与部分 GROUP BY 列表的 ROLLUP
在下例中,GROUPING SETS
列表包含列 T.[Group]
和 T.CountryRegionCode
的分组以及列 S.Name
和 H.SalesPersonID
的 ROLLUP
。
复制代码 | |
---|---|
USE AdventureWorks; GO SELECT T.[Group] AS N'Region', T.CountryRegionCode AS N'Country' ,S.Name AS N'Store', H.SalesPersonID ,SUM(TotalDue) AS N'Total Sales' FROM Sales.Customer C INNER JOIN Sales.Store S ON C.CustomerID = S.CustomerID INNER JOIN Sales.SalesTerritory T ON C.TerritoryID = T.TerritoryID INNER JOIN Sales.SalesOrderHeader H ON S.CustomerID = H.CustomerID WHERE T.[Group] = N'Europe' AND T.CountryRegionCode IN(N'DE', N'FR') AND H.SalesPersonID IN(284, 286, 289) AND SUBSTRING(S.Name,1,4)IN(N'Vers', N'Spa ') GROUP BY GROUPING SETS( T.[Group], T.CountryRegionCode ,ROLLUP(S.Name, H.SalesPersonID)) ORDER BY T.[Group], T.CountryRegionCode, S.Name, H.SalesPersonID; |
下面是结果集:
Region | Country | Store | SalesPersonID | Total Sales |
---|---|---|---|---|
NULL |
NULL |
NULL |
NULL |
297597.8 |
NULL |
NULL |
Spa and Exercise Outfitters |
NULL |
279046.8 |
NULL |
NULL |
Spa and Exercise Outfitters |
284 |
32774.36 |
NULL |
NULL |
Spa and Exercise Outfitters |
286 |
246272.4 |
NULL |
NULL |
Versatile Sporting Goods Company |
NULL |
18551.07 |
NULL |
NULL |
Versatile Sporting Goods Company |
284 |
859.232 |
NULL |
NULL |
Versatile Sporting Goods Company |
289 |
17691.83 |
NULL |
DE |
NULL |
NULL |
18551.07 |
NULL |
FR |
NULL |
NULL |
279046.8 |
Europe |
NULL |
NULL |
NULL |
297597.8 |
K. 使用 GROUPING SETS 与部分 GROUP BY 列表的 CUBE
在下例中,GROUPING SETS
列表包含列 T.[Group]
和 T.CountryRegionCode
的分组以及列 S.Name
和 H.SalesPersonID
的 CUBE
。
USE AdventureWorks; GO SELECT T.[Group] AS N'Region', T.CountryRegionCode AS N'Country' ,S.Name AS N'Store', H.SalesPersonID ,SUM(TotalDue) AS N'Total Sales' FROM Sales.Customer C INNER JOIN Sales.Store S ON C.CustomerID = S.CustomerID INNER JOIN Sales.SalesTerritory T ON C.TerritoryID = T.TerritoryID INNER JOIN Sales.SalesOrderHeader H ON S.CustomerID = H.CustomerID WHERE T.[Group] = N'Europe' AND T.CountryRegionCode IN(N'DE', N'FR') AND H.SalesPersonID IN(284, 286, 289) AND SUBSTRING(S.Name,1,4)IN(N'Vers', N'Spa ') GROUP BY GROUPING SETS( T.[Group], T.CountryRegionCode ,CUBE(S.Name, H.SalesPersonID)) ORDER BY T.[Group], T.CountryRegionCode, S.Name, H.SalesPersonID; |
下面是结果集:
Region | Country | Store | SalesPersonID | Total Sales |
---|---|---|---|---|
NULL |
NULL |
NULL |
NULL |
297597.8 |
NULL |
NULL |
NULL |
284 |
33633.59 |
NULL |
NULL |
NULL |
286 |
246272.4 |
NULL |
NULL |
NULL |
289 |
17691.83 |
NULL |
NULL |
Spa and Exercise Outfitters |
NULL |
279046.8 |
NULL |
NULL |
Spa and Exercise Outfitters |
284 |
32774.36 |
NULL |
NULL |
Spa and Exercise Outfitters |
286 |
246272.4 |
NULL |
NULL |
Versatile Sporting Goods Company |
NULL |
18551.07 |
NULL |
NULL |
Versatile Sporting Goods Company |
284 |
859.232 |
NULL |
NULL |
Versatile Sporting Goods Company |
289 |
17691.83 |
NULL |
DE |
NULL |
NULL |
18551.07 |
NULL |
FR |
NULL |
NULL |
279046.8 |
Europe |
NULL |
NULL |
NULL |
297597.8 |