【hive】cube和rollup/grouping sets函数

本文深入解析数据立方体的概念,探讨其在数据仓库设计中的应用,以及如何通过Hive中的cube函数进行多维度聚合查询,同时对比groupingsets和rollup函数的使用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

cube

  • 数据立方体(Data Cube),是多维模型的一个形象的说法.(关于多维模型这里不讲述,在数据仓库设计过程中还挺重要的,有兴趣自行查阅)
  • 立方体其本身只有三维,但多维模型不仅限于三维模型,可以组合更多的维度
  • 为什么叫数据立方体?
    • 一方面是出于更方便地解释和描述,同时也是给思维成像和想象的空间;
    • 另一方面是为了与传统关系型数据库的二维表区别开来

下图为数据立方体的形象图
数据立方体

  • 其实并不用把cube理解得很高大上,只要理解为分别按照不同维度进行聚合.
  • hive中也有cube函数,可以实现多个任意维度的查询
    • cube(a,b,c)则首先会对(a,b,c)进行group by,
    • 然后依次是(a,b),(a,c),(a),(b,c),(b),(c),最后在对全表进行group by,他会统计所选列中值的所有组合的聚合
    • 用cube函数就可以完成所有维度的聚合工作.

语法

select col1,col2,col3,col4, --维度字段
         count(user_id),  --聚合字段
         GROUPING__ID, --聚合选取的组号(二进制表示,但是这里打印出来的是十进制)
         rpad(reverse(bin(cast(GROUPING__ID AS bigint))),4,'0') --对其二进制化就能明白了,注意中间是两个下划线,因为在反转的时候会把末尾的0去掉,需要用rpad补充至维度个数
from table 
group by col1,col2,col3,col4  --维度字段都要出现在group by中,这里不能使用1,2,3,4代替
with cube; --使用cube函数
  • 如果我们想要手动实现cube函数就需要把所有维度的聚合都用union all来汇总.
  • 可以说cube函数方便了用户的使用.
  • 但是我并不用知道所有维度的聚合,我就想要col1,(col2,col3)的怎么办?

grouping sets

  • 当不需要cube将所有维度都列出来的时候,当只需要部分维度的时候
  • 可以使用grouping sets来进行决定聚合那些维度

语法

select col1,col2,col3, --维度字段
         count(user_id),  --聚合字段
         GROUPING__ID, --聚合选取的组号(二进制表示,但是这里打印出来的是十进制)
        rpad(reverse(bin(cast(GROUPING__ID AS bigint))),3,'0') --对其二进制化就能明白了,注意中间是两个下划线,注意中间是两个下划线,因为在反转的时候会把末尾的0去掉,需要用rpad补充至维度个数
from table 
group by col1,col2,col3  --维度字段都要出现在group by中,并不能省略暂时不用到的字段,这里不能使用1,2,3,4代替
grouping sets(col1,(col2,col3)); --使用grouping sets来代替with cube
  • 注意:当使用grouping sets()进行指定维度聚合的时候,仅仅聚合你给出的维度组合,并不会自动帮你组合维度.
    • 例如 grouping sets(col1,(col2,col3)) 只聚合col1维度,(col2,col3)维度.
    • 并不会自动聚合(col1,col2,col3)维度

rollup

  • rullup函数是cube的子集,以最左侧维度为主,按照顺序依次进行聚合.
  • 例如聚合的维度为 col1,col2,col3 使用rollup聚合的字段分别为 col1,(col1,col2),(col1,col3),(col1,col2,col3)

语法

select col1,col2,col3,col4, --维度字段
         count(user_id),  --聚合字段
         GROUPING__ID, --聚合选取的组号(二进制表示,但是这里打印出来的是十进制)
         rpad(reverse(bin(cast(GROUPING__ID AS bigint))),4,'0') --对其二进制化就能明白了,注意中间是两个下划线,注意中间是两个下划线,因为在反转的时候会把末尾的0去掉,需要用rpad补充至维度个数
from table 
group by col1,col2,col3,col4  --维度字段都要出现在group by中,这里不能使用1,2,3,4代替
with rollup; --使用rollup函数

如何查看根据什么维度聚合呢?

select user_type,sales, --维度
         count(user_id) as pv, --聚合字段
         grouping__id,
         rpad(reverse(bin(cast(GROUPING__ID AS bigint))),2,'0') as sign --grouping__id逆序
from user_info
group by user_type,sales
with cube;

查询结果如下

user_typesalespvgrouping__idsign
NULLNULL10000
oldNULL3110
newNULL7110
old31311
old21311
old11311
new61311
new52311
new31311
new21311
new123 .11
  • 上面是使用cube函数聚合后的数据
  • 可以根据 GROUPING__ID 的二进制表示形式(反向)直接看出.
    • 这里使用聚合的维度有user_type和sales两个维度,如果使用当前维度,对应bin(grouping__id)数字为1
    • 例如 第二行数据的 10 -> 使用了user_type维度,没使用sales
  • 可以通过聚合后的数据看出
    • 当改字段为NULL的时候,说明没有使用该字段维度.
    • 例如 第二行数据 old NULL -> 使用了user_type维度,没使用sales
### 使用 Hive 中 `GROUPING SETS` 的方法 #### 示例与语法解释 在 Hive SQL 查询中,`GROUPING SETS` 提供了一种简洁的方式来执行多维分组聚合。这使得可以在单个查询中指定多个不同的组合来进行数据汇总。 创建表并插入测试数据: ```sql CREATE TABLE IF NOT EXISTS student_scores ( class STRING, sex STRING, course STRING, score INT ); INSERT INTO student_scores VALUES ('ClassA', 'Male', 'Math', 80), ('ClassB', 'Female', 'English', 90), ('ClassA', 'Female', 'Math', 75); ``` 使用 `GROUPING SETS` 执行复杂分组操作: ```sql SELECT GROUPING__ID, -- 特殊列用于区分不同层次的分组结果 class, sex, course, AVG(score) AS average_score FROM student_scores GROUP BY class, sex, course WITH ROLLUP; -- 或者使用 CUBE 替代 ROLLUP 来获取更全面的结果集 ``` 上述例子展示了如何利用 `WITH ROLLUP` 关键字来简化某些类型的 `GROUPING SETS` 定义[^1]。对于更加复杂的场景,则可以直接定义具体的分组集合: ```sql SELECT GROUPING__ID, class, sex, course, AVG(score) AS average_score FROM student_scores GROUP BY class, sex, course GROUPING SETS( (class, course), (class, sex), (sex, course), () -- 表示全局总计行 ); ``` 此查询会返回四类不同的分组统计信息:按班级课程、按性别课程、仅限于特定科目以及整个表格的整体平均成绩[^3]。 注意,在输出结果集中有一个名为 `GROUPING__ID` 的特殊字段,它用来指示当前记录对应的是哪种级别的分组情况。通过检查该值可以帮助理解每一行代表的数据范围[^2]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值