hive 之 Cube, Rollup介绍

本文介绍了Hive SQL中的统计函数和窗口函数。统计函数包括GROUPING SETS、CUBE函数、ROLL UP函数和Grouping_ID函数,GROUPING SETS可指定多个统计维度,CUBE能实现多维度查询,ROLL UP可递减多级统计,Grouping_ID可区分统计与列本身的null值。还提及了窗口函数,可参考相关文档。

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

1. GROUPING SETS

GROUPING SETS作为GROUP BY的子句,允许开发人员在GROUP BY语句后面指定多个统维度,可以简单理解为多条group by语句通过union all把查询结果聚合起来结合起来。

为方便理解,以testdb.test_1为例:

hive> use testdb;
hive> desc test_1;

user_id        string      id                
device_id      string      设备类型:手机、平板             
os_id          string      操作系统类型:ios、android            
app_id         string      手机app_id             
client_v       string      客户端版本             
channel        string      渠道
grouping sets语句等价hive语句
select device_id,os_id,app_id,count(user_id) from  test_1 group by device_id,os_id,app_id grouping sets((device_id)) SELECT device_id,null,null,count(user_id) FROM test_1 group by device_id
select device_id,os_id,app_id,count(user_id) from  test_1 group by device_id,os_id,app_id grouping sets((device_id,os_id))SELECT device_id,os_id,null,count(user_id) FROM test_1 group by device_id,os_id
select device_id,os_id,app_id,count(user_id) from  test_1 group by device_id,os_id,app_id grouping sets((device_id,os_id),(device_id))SELECT device_id,os_id,null,count(user_id) FROM test_1 group by device_id,os_id UNION ALL SELECT device_id,null,null,count(user_id) FROM test_1 group by device_id
select device_id,os_id,app_id,count(user_id) from  test_1 group by device_id,os_id,app_id grouping sets((device_id),(os_id),(device_id,os_id),())SELECT device_id,null,null,count(user_id) FROM test_1 group by device_id UNION ALL SELECT null,os_id,null,count(user_id) FROM test_1 group by os_id UNION ALL SELECT device_id,os_id,null,count(user_id) FROM test_1 group by device_id,os_id  UNION ALL SELECT null,null,null,count(user_id) FROM test_1

2. CUBE函数

cube简称数据魔方,可以实现hive多个任意维度的查询,cube(a,b,c)则首先会对(a,b,c)进行group by,然后依次是(a,b),(a,c),(a),(b,c),(b),(c),最后在对全表进行group by,cube会统计所选列中值的所有组合的聚合

select device_id,os_id,app_id,client_v,channel,count(user_id) 
from test_1 
group by device_id,os_id,app_id,client_v,channel with cube;

等价于:

SELECT device_id,null,null,null,null ,count(user_id) FROM test_1 group by device_id
UNION ALL
SELECT null,os_id,null,null,null ,count(user_id) FROM test_1 group by os_id
UNION ALL
SELECT device_id,os_id,null,null,null ,count(user_id) FROM test_1 group by device_id,os_id
UNION ALL
SELECT null,null,app_id,null,null ,count(user_id) FROM test_1 group by app_id
UNION ALL
SELECT device_id,null,app_id,null,null ,count(user_id) FROM test_1 group by device_id,app_id
UNION ALL
SELECT null,os_id,app_id,null,null ,count(user_id) FROM test_1 group by os_id,app_id
UNION ALL
SELECT device_id,os_id,app_id,null,null ,count(user_id) FROM test_1 group by device_id,os_id,app_id
UNION ALL
SELECT null,null,null,client_v,null ,count(user_id) FROM test_1 group by client_v
UNION ALL
SELECT device_id,null,null,client_v,null ,count(user_id) FROM test_1 group by device_id,client_v
UNION ALL
SELECT null,os_id,null,client_v,null ,count(user_id) FROM test_1 group by os_id,client_v
UNION ALL
SELECT device_id,os_id,null,client_v,null ,count(user_id) FROM test_1 group by device_id,os_id,client_v
UNION ALL
SELECT null,null,app_id,client_v,null ,count(user_id) FROM test_1 group by app_id,client_v
UNION ALL
SELECT device_id,null,app_id,client_v,null ,count(user_id) FROM test_1 group by device_id,app_id,client_v
UNION ALL
SELECT null,os_id,app_id,client_v,null ,count(user_id) FROM test_1 group by os_id,app_id,client_v
UNION ALL
SELECT device_id,os_id,app_id,client_v,null ,count(user_id) FROM test_1 group by device_id,os_id,app_id,client_v
UNION ALL
SELECT null,null,null,null,channel ,count(user_id) FROM test_1 group by channel
UNION ALL
SELECT device_id,null,null,null,channel ,count(user_id) FROM test_1 group by device_id,channel
UNION ALL
SELECT null,os_id,null,null,channel ,count(user_id) FROM test_1 group by os_id,channel
UNION ALL
SELECT device_id,os_id,null,null,channel ,count(user_id) FROM test_1 group by device_id,os_id,channel
UNION ALL
SELECT null,null,app_id,null,channel ,count(user_id) FROM test_1 group by app_id,channel
UNION ALL
SELECT device_id,null,app_id,null,channel ,count(user_id) FROM test_1 group by device_id,app_id,channel
UNION ALL
SELECT null,os_id,app_id,null,channel ,count(user_id) FROM test_1 group by os_id,app_id,channel
UNION ALL
SELECT device_id,os_id,app_id,null,channel ,count(user_id) FROM test_1 group by device_id,os_id,app_id,channel
UNION ALL
SELECT null,null,null,client_v,channel ,count(user_id) FROM test_1 group by client_v,channel
UNION ALL
SELECT device_id,null,null,client_v,channel ,count(user_id) FROM test_1 group by device_id,client_v,channel
UNION ALL
SELECT null,os_id,null,client_v,channel ,count(user_id) FROM test_1 group by os_id,client_v,channel
UNION ALL
SELECT device_id,os_id,null,client_v,channel ,count(user_id) FROM test_1 group by device_id,os_id,client_v,channel
UNION ALL
SELECT null,null,app_id,client_v,channel ,count(user_id) FROM test_1 group by app_id,client_v,channel
UNION ALL
SELECT device_id,null,app_id,client_v,channel ,count(user_id) FROM test_1 group by device_id,app_id,client_v,channel
UNION ALL
SELECT null,os_id,app_id,client_v,channel ,count(user_id) FROM test_1 group by os_id,app_id,client_v,channel
UNION ALL
SELECT device_id,os_id,app_id,client_v,channel ,count(user_id) FROM test_1 group by device_id,os_id,app_id,client_v,channel
UNION ALL
SELECT null,null,null,null,null ,count(user_id) FROM test_1

3. ROLL UP函数

rollup可以实现从右到左递减多级的统计,显示统计某一层次结构的聚合

select device_id,os_id,app_id,client_v,channel,count(user_id) 
from test_1 
group by device_id,os_id,app_id,client_v,channel with rollup;

等价于:

select device_id,os_id,app_id,client_v,channel,count(user_id) 
from test_1 
group by device_id,os_id,app_id,client_v,channel 
grouping sets ((device_id,os_id,app_id,client_v,channel),(device_id,os_id,app_id,client_v),(device_id,os_id,app_id),(device_id,os_id),(device_id),());

4.Grouping_ID函数

当我们没有统计某一列时,它的值显示为null,这可能与列本身就有null值冲突,这就需要一种方法区分是没有统计还是值本来就是null。(写一个排列组合的算法,就马上理解了,grouping_id其实就是所统计各列二进制和)

例子如下:

Column1 (key)Column2 (value)
1NULL
11
22
33
3NULL
45

hql统计:

  SELECT key, value, GROUPING_ID, count(*) from T1 GROUP BY key, value WITH ROLLUP

结果如下:

 keyvalueGROUPING_ID count(*) 
NULLNULL0     006
1NULL1     102
1NULL3     111
113     111
2NULL1     101
223     111
3NULL1     102
3NULL3     111
333     111
4NULL1     101
453     111

GROUPING_ID转变为二进制,如果对应位上有值为null,说明这列本身值就是null。(通过类DataFilterNull.py 扫描,可以筛选过滤掉列中null、“”统计结果),

5. 窗口函数

hive窗口函数,感觉大部分都是在模仿oracle,有对oracle熟悉的,应该看下就知道怎么用。

具体参见:http://docs.hortonworks.com/HDPDocuments/HDP2/HDP-2.0.0.2/ds_Hive/language_manual/ptf-window.html

参考文章

  1. https://blog.youkuaiyun.com/gua___gua/article/details/52523698

转载于:https://www.cnblogs.com/remainsu/p/11060580.html

### Hive SQL Cube 使用示例 Cube 是一种强大的聚合工具,在 Hive 中用于生成多维分析的结果集。通过 `CUBE` 关键字,可以自动计算所有可能的组合维度上的聚合结果。 #### 示例 1:基本 CUBE 使用 假设有一个销售数据表 `sales`,包含字段 `region`(地区)、`product`(产品)和 `amount`(销售额)。以下是使用 `CUBE` 的简单例子: ```sql SELECT region, product, SUM(amount) AS total_sales FROM sales GROUP BY region, product WITH CUBE; ``` 上述查询不仅会返回按 `region` 和 `product` 组合的聚合结果,还会额外提供以下几种情况下的总和: - 每个地区的总计销售额(忽略产品) - 每种产品的总计销售额(忽略地区) - 整体的总计销售额(忽略地区和产品) 这相当于手动执行多个分组操作并将其结果合并在一起的效果[^1]。 --- #### 示例 2:带有过滤条件的 CUBE 查询 如果希望在应用 `CUBE` 之前先筛选部分数据,则可以在 `WHERE` 子句中指定条件。例如,仅统计金额大于 100 的记录: ```sql SELECT region, product, SUM(amount) AS total_sales FROM sales WHERE amount > 100 GROUP BY region, product WITH CUBE; ``` 此语句会在满足条件的基础上继续扩展所有的维度组合[^2]。 --- #### 示例 3:结合 ROLLUP 进行更灵活控制 虽然 `CUBE` 提供了全面的维度组合,但在某些情况下只需要特定层次结构的汇总而非全部可能性时,可以选择 `ROLLUP` 或混合两者来达到目的。比如下面的例子展示了如何优先考虑区域层面的整体趋势再深入具体商品表现: ```sql -- 结合 rollup 只关注更高层面上的变化规律 SELECT region, product, SUM(amount) AS total_sales FROM sales GROUP BY region, product WITH ROLLUP; -- 如果想保留 cube 功能又不想完全展开则可这样写 SELECT COALESCE(region,'All_Regions') as reg, COALESCE(product,'All_Products') prod, sum(amount) FROM sales GROUP BY GROUPING SETS ((region), (product), (), (region, product)); ``` 这里利用了 `COALESCE()` 函数处理 NULL 值以便于阅读最终报表中的超级合计项名称;而 `GROUPING SETS` 则允许精确定义哪些集合应该被包括进来从而避免不必要的冗余运算过程发生[^3]。 --- #### 性能调优建议 当面对大规模数据集运行涉及复杂聚集操作如立方体构建之类的任务时需要注意性能问题。可以通过以下几个方面来进行改善: - **压缩输入文件大小**: 对原始日志进行预处理去掉无关列减少传输开销。 - **调整mapreduce参数设置**, 如增大split size让mapper数量更加合理分布防止过多小job启动消耗资源. - 应用前面提到过的那些关于joins以及filters的最佳实践同样适用于此处因为它们直接影响到底层mr框架的工作效率.[^4] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值