分組集(Grouping Sets)是多個分組的並集,用於在一個查詢中,按照不同的分組列對集合進行聚合運算,等價於對單個分組使用“union all”,計算多個結果集的並集。使用分組集的聚合查詢,返回的select 子句相同,由於select子句只能引用分組列,因此,在單個分組中缺失的分組列,TSQL返回NULL值。
TSQL使用 group by 子句分組,有4種不同的語法:
- group by a,b
- group by rollup(a,b)
- group by cube(a,b)
- group by grouping sets((),(a),(a,b),rollup(a,b),cube(a,b))
一,分組集
1,單個分組
以集合的視角來看 “group by a,b” 子句,等價於 “group by grouping sets (a,b)”,(a,b) 是單個分組,是集合相乘的結果:(a)*(b)=(a,b) ;
2,預定義的分組集(grouping sets):
- rollup(a,b) :預定義的分組集是(),(a),(a,b);
- cube(a,b) :預定義的的分組集是(),(a),(b),(a,b);
3,使用grouping sets 自定義分組集
單個分組的集合是分組集, 分組集 grouping sets((a),(a,b)) :表示兩個分組 (a,b),(a) 的並集,查詢的結果等價於:
group by (a,b) union all group by(a)
4,分組集運算
分組集運算法則:
- () :表示空集,整個集合作為一個分組;任何集合和空集相乘,結果是:(a)*()=(a);
- 分組集相乘:兩兩組合,例如,{(a),(b)}*{(c),(d)}={(a,c),(a,d),(b,c),(b,d)}
- 集合相乘時,不會去重:例如,{(a),(b)}*{(),(a)}={(a),(a,a),(b),(b,a)}
- (a,a)等價於集合(a):例如,{(a),(b)}*{(),(a)}={(a),(a),(b),(b,a)}
- group by是分組集相乘:例如, group by grouping sets((a),(b)),c 等價於 group by grouping sets((a,c),(b,c))
- grouping sets是分組集求並集,不會去重:例如,grouping sets((a),(a)) 等價於 grouping sets(a) union all grouping sets(a)
4.1,解析:grouping sets(rollup(a,b),b) 等價於 group by cube(a,b)
解析過程:rollup(a,b)定義的分組集是(),(a),(a,b),並上分組(b),就是:((),(a),(a,b),(b)),等價於cube(a,b)。
4.2,解析 group by grouping sets((a),(b)), rollup(a)
解析過程:grouping sets((a),(b)),定義兩個分組集合((a),(b)),rollup(a)定義兩個分組集合:((),(a)),
兩個分組集進行相乘:{(a),(b)}*{(),(a)}={(a),(a),(b),(b,a)},集合相乘時,不會去重;
二,示例
1,創建示例數據
create table dbo.Inventory ( Item int not null, Color varchar(10) not null, Quantity int not null, Store int not null )
2,將整個集合作為一個分組,grouping sets 是()
select null as Item, null as Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from dbo.Inventory --等價於 select null as Item, null as Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from dbo.Inventory group by grouping sets(())
3,grouping sets是(a)
select Item,null as Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from dbo.Inventory group by Item order by Item --等價於 select Item,null as Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from dbo.Inventory group by grouping sets( (Item)) order by Item
4,grouping sets 是(a,b)
select Item,Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from Inventory group by Item,Color order by Item,Color --等價於 select Item,Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from Inventory group by grouping sets( (Item,Color)) order by Item,Color
5,分組集是:rollup(a,b),或 grouping sets是((),(a),(a,b))
--rollup(a,b)的grouping sets是(),(a),(a,b) select Item,Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from dbo.Inventory group by ROLLUP(Item,Color) order by Item,Color --等價於 select Item,Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from dbo.Inventory group by grouping sets((),(Item),(Item,Color)) order by Item,Color
6,分組集是:cube(a,b),或grouping sets是(),(a),(b),(a,b)
--cube(a,b)的grouping sets是(),(a),(b),(a,b) select Item,Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from dbo.Inventory group by ROLLUP(Item,Color) order by Item,Color --等價於 select Item,Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from dbo.Inventory group by grouping sets((),(Item),(Color),(Item,Color)) order by Item,Color
7,對rollup(a,b),使用單個分組和union來實現
--rollup(a,b)的grouping sets是(),(a),(a,b) select Item,Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from dbo.Inventory group by ROLLUP(Item,Color) order by Item,Color --等價於 select null as Item, null as Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from dbo.Inventory union ALL select Item,null as Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from dbo.Inventory group by Item union ALL select Item,Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from dbo.Inventory group by Item,Color
8,對cube(a,b),使用單個分組和union來實現
--cube(a,b)的grouping sets是(),(a),(b),(a,b) select Item,Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from dbo.Inventory group by cube(Item,Color) order by Item,Color --等價於 select null as Item, null as Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from dbo.Inventory union ALL select Item,null as Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from dbo.Inventory group by Item union ALL select null as Item,Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from dbo.Inventory group by Color union all select Item,Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from dbo.Inventory group by Item,Color
9, cube(a,b)的等價分組集是:grouping sets(rollup(a,b),b),或grouping sets((),(a),(a,b),(b))
--cube(a,b)的組合是(),(a),(b),(a,b) select Item,Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from Inventory group by CUBE( Item,Color) order by Item,Color --等價於 select Item,Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from dbo.Inventory group by grouping sets((),(Item),(Color),(Item,Color)) order by Item,Color --等價於 select Item,Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from dbo.Inventory group by grouping sets(rollup(Item,Color),(Color)) order by Item,Color
10,分組集相乘,結果集不去重
解析 grouping sets((a),(b)), rollup(a)等價於 grouping((a),(a),(b),(b,a))
解析過程是:grouping sets((a),(b)), 定義兩個分組集是(a),(b),rollup(a)定義兩個分組集是:(),(a)
對這個分組集進行集合乘法運算:{(a),(b)}*{(),(a)}={(a),(a),(b),(b,a)}
select Item,Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from dbo.Inventory group by grouping sets((Item),(Color)),rollup(Item) order by Item,Color --等價於 select Item,Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from dbo.Inventory group by grouping sets((Item),(Color),(Item,Item),(Color,Item)) order by Item,Color
解析: grouping sets((a,b)),rollup(a)
解析過程:grouping sets((a,b)),定義分組集(a,b),rollup(a)定義分組集:{(),(a)},對這兩個分組集合進行集合乘法運算:(a,b)*{(),(a)}={(a,b),(a,b)},實際上是兩個相同的group by grouping sets((a,b)) 進行 union all 運算求並集。
select Item,Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from dbo.Inventory group by grouping sets((Item,Color)),rollup(Item) order by Item,Color --等價於 select Item,Color,SUM(Quantity) as TotalQuantity,COUNT(Store) as Stores from dbo.Inventory group by grouping sets((Item,Color),(Color,Item)) order by Item,Color
三,分組集用法總結
1, cube和rollup 預定義grouping sets,
- rollup(a,b):預定義的grouping sets是(),(a),(a,b);
- cube(a,b):預定義的grouping sets是(),(a),(b),(a,b);
2,集合的乘法
group by a,b 表示的是分組集(a),(b)的乘法:(a)*(b)=(a,b)
group by grouping sets((a),(b)),c 表示的是分組集((a),(b)),(c)的乘法:((a),(b))*(c)=((a,c),(b,c))
3,集合的並集
grouping sets((a),(b)),表示的是分組集的並集,等價於:
grouping sets(a) union all grouping sets(b)
參考文檔: