使用 grouping 区分空值
cube 操作所生成的空值带来一个问题:如何区分 cube 操作所生成的 null 值和从实际数据中返回的 null 值?这个问题可用 grouping 函数解决。如果列中的值来自事实数据,则 grouping 函数返回 0;如果列中的值是 cube 操作所生成的 null,则返回 1。在 cube 操作中,所生成的 null 代表全体值。可将 select 语句写成使用 grouping 函数将所生成的 null 替换为字符串 all。因为事实数据中的 null 表明数据值未知,所以 select 语句还可译码为返回字符串 unknown 替代来自事实数据的 null。例如:
select case when (grouping(item) = 1) then 'all'
else isnull(item, 'unknown')
end as item,
case when (grouping(color) = 1) then 'all'
else isnull(color, 'unknown')
end as color,
sum(quantity) as qtysum
from inventory
group by item, color with cube
多维数据集
cube 运算符可用于生成 n 维的多维数据集,即具有任意数目维度的多维数据集。只有一个维度的多维数据集可用于生成合计,例如:
select case when (grouping(item) = 1) then 'all'
else isnull(item, 'unknown')
end as item,
sum(quantity) as qtysum
from inventory
group by item with cube
go
此 select 语句返回的结果集既显示了 item 中每个值的小计,也显示了 item 中所有值的总计:
item qtysum
-------------------- --------------------------
chair 311.00
table 347.00
all 658.00
包含带有许多维度的 cube 的 select 语句可能生成很大的结果集,因为这些语句会为所有维度中值的所有组合生成行。这些大结果集包含的数据可能过多而不易于阅读和理解。这个问题有一种解决办法是将 select 语句放在视图中:
create view invcube as
select case when (grouping(item) = 1) then 'all'
else isnull(item, 'unknown')
end as item,
case when (grouping(color) = 1) then 'all'
else isnull(color, 'unknown')
end as color,
sum(quantity) as qtysum
from inventory
group by item, color with cube
然后即可用该视图来只查询您感兴趣的维度值:
select *
from invcube
where item = 'chair'
and color = 'all'
item color qtysum
-------------------- -------------------- --------------------------
chair all 311.00
(1 row(s) affected)
用 rollup 汇总数据
在生成包含小计和合计的报表时,rollup 运算符很有用。rollup 运算符生成的结果集类似于 cube 运算符所生成的结果集。有关更多信息,请参见用 cube 汇总数据。
cube 和 rollup 之间的区别在于:
- cube 生成的结果集显示了所选列中值的所有组合的聚合。
- rollup 生成的结果集显示了所选列中值的某一层次结构的聚合。
例如,简单表 inventory 中包含:
item color quantity
-------------------- -------------------- --------------------------
table blue 124
table red 223
chair blue 101
chair red 210
下列查询将生成小计报表:
select case when (grouping(item) = 1) then 'all'
else isnull(item, 'unknown')
end as item,
case when (grouping(color) = 1) then 'all'
else isnull(color, 'unknown')
end as color,
sum(quantity) as qtysum
from inventory
group by item, color with rollup
item color qtysum
-------------------- -------------------- --------------------------
chair blue 101.00
chair red 210.00
chair all 311.00
table blue 124.00
table red 223.00
table all 347.00
all all 658.00
(7 row(s) affected)
如果查询中的 rollup 关键字更改为 cube,那么 cube 结果集与上述结果相同,只是在结果集的末尾还会返回下列两行:
all blue 225.00
all red 433.00
cube 操作为 item 和 color 中值的可能组合生成行。例如,cube 不仅报告与 item 值 chair 相组合的 color 值的所有可能组合(red、blue 和 red + blue),而且报告与 color 值 red 相组合的 item 值的所有可能组合(chair、table 和 chair + table)。
对于 group by 子句中右边的列中的每个值,rollup 操作并不报告左边一列(或左边各列)中值的所有可能组合。例如,rollup 并不对每个 color 值报告 item 值的所有可能组合。
rollup 操作的结果集具有类似于 compute by 所返回结果集的功能;然而,rollup 具有下列优点: