共计 1092 个字符,预计需要花费 3 分钟才能阅读完成。
背景
需要对多个维度的数据做不同维度的聚合操作,正常情况下你想要的统计维度需要单独通过一个SQl来实现,那么有多个维度可能就需要多个SQl。
举个例子,有班级、性别、分数,现在我想要统计
- 每个班级的平均分数
- 每类性别的平均分数
- 统计每个班级、每类性别下的平均分数
那么假想的情况是
select class,avg(score) from XXXXX group by class
select sex,avg(score) from XXXXX group by sex
select class,sex,avg(score) from XXXXX group by class,sex
grouping sets
ok,到这里就会引出今天要讲的 grouping sets 了,它的优势就是可以使用一条SQL来完成上述的需求。
select
grouping__id, -- 内置变量,只要使用grouping sets就可以调用
class,
sex,
avg(score) as avg_score
from
XXXXX
group by
class,
sex
grouping sets(
class,
sex,
(class, sex)
)
这里会出现一个关键词 grouping__id ,这个 grouping__id是什么?
在上面的例子中我们企图对三种维度进行聚合,那么这个 grouping__id就是对三种情况进行编码
- 将 group by 的所有字段 倒序 排列。
- 对于每个字段,如果该字段出现在了当前粒度中,则该字段位置赋值为1,否则为0。
- 这样就形成了一个二进制数,这个二进制数转为十进制,即为当前粒度对应的 grouping__id。
序号 | group set | 二进制编码 | 十进制编码 |
---|---|---|---|
1 | class | 01 | 1 |
2 | sex | 10 | 2 |
3 | class,sex | 11 | 3 |
关于grouping sets 的使用注意事项:
- grouping sets 只能用于 group by 之后。
- grouping sets 中可以包含多种粒度,粒度之间用逗号连接。
- grouping sets 中的所有字段,都必须出现在 group by 中,相当于 group by 后面的字段是最细粒度。
- 如果 select 中的字段,没有包含在某个 grouping set 中,那么这个粒度下的这个字段值为 NULL。
- 不同的粒度,可以使用内置变量 grouping__id 进行区分。
所以在前面写的SQL的执行结果大概如下所示:
grouping__id | class | sex | AVG(score) |
---|---|---|---|
1 | 1 | NULL | XXX |
1 | 2 | NULL | XXX |
2 | NULL | 1 | XXX |
2 | NULL | 2 | XXX |
3 | 1 | 1 | XXX |
3 | 1 | 2 | XXX |
3 | 2 | 1 | XXX |
3 | 2 | 1 | XXX |
差不多到这就讲到这里,基本上知道了 grouping sets 的使用方法,下次就知道这么用了,学会了新招。
正文完
请博主喝杯咖啡吧!