• grouping sets: 根据不同的维度组合进行聚合,等价于将不同维度的group by结果集进行union all
  • grouping__id(请注意函数名中的下划线是两个!):表示结果属于哪一个分组集合,属于虚字段
  • cube: 根据group by的维度的所有组合进行聚合。
  • rollup: 为cube的子集,以最左侧的维度为主,从该维度进行层级聚合。(从右向左依次递减)

这几个分析函数通常用于,根据不同维度上钻和下钻的指标统计,比如,分小时、天、月的uv数
在一个group by查询中,根据不同的维度组合进行聚合,等价于将不同维度的group by结果集进行union all。
通俗的说,grouping sets是一种将多个group by 逻辑写在一个语句中的便利写法

上卷(roll-up):上卷是沿着维的层次向上聚集汇总数据。例如,对产品销售数据,沿着时间维上卷,可以求出所有产品在所有地区每月(或季度或年或全部)的销售额。
下探(drill-down):下探是上卷的逆操作,它是沿着维的层次向下,查看更详细的数据。
希望能帮助你理解。

数据:

10001    2007-12-24  2   A   1200
10005   2007-12-24  1   B   2000
10006   2008-01-18  1   C   1400
20001   2008-02-12  2   B   1200
20002   2009-02-16  1   C   2000
30001   2007-08-02  3   A   1000
30003   2009-04-18  2   B   1500
30004   2009-04-18  3   C   2200
30007   2009-09-07  3   D   3000
40001   2008-01-09  2   A   4000
40005   2009-02-12  3   A   1000

准备工作

create table orders(orderid int, orderdate date, empid int,    custid string,  qty int
)
row format delimited fields terminated by '\t';load data local inpath '/opt/module/hive/datas/Orders.txt' into table orders;select*from orders;

– 1. 汇总每年收入

selectyear(orderdate) orderyear,sum(qty) sum_qty
from Orders
group by year(orderdate)
order by orderyear;

– 2. 公司每个月的收入

selectyear(orderdate) orderyear,month(orderdate) ordermonth,sum(qty) sum_qty
from Orders
group by year(orderdate),month(orderdate)
order by orderyear,ordermonth;

– 3. 公司收入(每年|每月)。1是按照年,2是按照年和月,汇总1、结果

-答案1

selectyear(orderdate) orderyear,null ordermonth,sum(qty) sum_qty
from Orders
group by year(orderdate)
union all
selectyear(orderdate) orderyear,month(orderdate) ordermonth,sum(qty) sum_qty
from Orders
group by year(orderdate),month(orderdate)
order by orderyear,ordermonth;

–null出现在里面按照年的汇总数据,非null为按照年和月的分组汇总

-答案2–用 GROUPING SETS实现相同结果

selectyear(orderdate) orderyear,month(orderdate) ordermonth,sum(qty) sum_qty,grouping__id  --表示结果属于哪一个分组集合,属于虚字段
from Orders
group by year(orderdate),month(orderdate)
grouping sets ( year(orderdate),  --1st grouping set(year(orderdate), month(orderdate)) --2nd grouping set);

–等价于

select year(orderdate) orderyear,null,sum(qty) sum_qty,1 as grouping__id from Orders group by year(orderdate)
union all
select year(orderdate) orderyear,month(orderdate) ordermonth,sum(qty) sum_qty,0 as grouping__id from Orders group by year(orderdate),month(orderdate);

–一个分组包含两个列,假设列A和B,两个列都需要包含在括号内:(column A, column B)。如果没有括号,这个子句将会被定义为独立的分组,结果就不同了。

selectyear(orderdate) orderyear,month(orderdate) ordermonth,sum(qty) sum_qty
from Orders
group by year(orderdate),month(orderdate)
grouping sets (year(orderdate), month(orderdate) );

– 4. 加入总体汇总结果

selectyear(orderdate) orderyear,month(orderdate) ordermonth,sum(qty) sum_qty,grouping__id
from Orders
group by year(orderdate),month(orderdate)
grouping sets ( year(orderdate), (year(orderdate), month(orderdate)), () );

–为啥没2??

selectyear(orderdate) orderyear,month(orderdate) ordermonth,sum(qty) sum_qty,(case grouping__id when 1 then '年度' when 0 then '年度|月度' else '总' end)
from Orders
group by year(orderdate),month(orderdate)
grouping sets ( year(orderdate), (year(orderdate), month(orderdate)), () );

1.在group by中使用rollup:

selectempid,avg(qty)
from Orders
group by empid;

–rollup是cube的子集,以最左侧的维度为主,从该维度进行层级聚合
–在生成原有统计结果基础上,生成横向小计结果。

selectnvl(empid, '所有订单平均') empid,avg(qty)
from Orders
group by rollup(empid);  --汇总的列返回的不是每个人的平均,而是所有行的平均(所有订单)

selectnvl(empid, '所有订单平均') empid,custid,avg(qty)
from Orders
group by rollup(empid, custid);

这里如果是group by rollup(a,b,c);对(a,b,c)三列分组的话,就是先对(a,b,c)进行group by,再对(a,b)进行group by,再对(a)进行group by,再对全表group by。从右向左依次递减

即rollup(1,2…n)时,group by的所有可能的group by数是n+1个,比如rollup(a,b,c);时,总共有4个汇总。

2.在group by中使用cube:

–cube操作符时,在生成原有统计结果基础上,生成纵向小计结果。
–根据GROUP BY的维度的所有组合进行聚合

selectempid,avg(qty)
from Orders
group by cube(empid);

selectnvl(empid, '订单平均') empid,custid,avg(qty)
from Orders
group by cube(empid, custid);

–另一种写法

selectmonth(orderdate) ordermonth,day(orderdate) orderday,sum(qty) sum_qty,grouping__id
from Orders
group by orderdate
with cube
order by grouping__id;

如果是group by cube(a,b,c);首先会对(a、b、c)进行group by,然后依次是(a、b),(a、c),(a),(b、c),(b),©,再对全表进行group by。

即cube(1,2,n)时,group by的所有可能的group by数是2的n次方,比如cube(a,b,c);时,总共有8个。

总结:rollup非常高效,对一个查询增加的开销非常少;cube相对更耗费资源。
在group by子句有列(a,b)两列时,rollup统计(a,b),(a);而cube统计了(a,b),(a),(b)。

4.grouping函数,区分出小计,汇总数据,只能在使用rollup或cube的查询中使用。

–对输入列返回0或1,如果该行数据使用了数据的列中的信息,即此列数据参与rollup/cube函数分组汇总活动,则输出0;没有用到则输出1

selectnvl(empid, '订单平均') empid,custid,avg(qty),grouping(empid) g_e,grouping(custid) g_c
from orders
group by rollup(empid, custid);


–通过在 having 子句中使用 grouping 函数,您可以只显示 empid 和 custid 组合的小计。

selectnvl(empid, '订单平均') empid,custid,avg(qty),grouping(empid) g_e,grouping(custid) g_c
from orders
group by rollup(empid, custid)
having grouping(custid) = 0;

–注意:有些表有一项由于表达式所基于的列对于表中的一行或多行为 null 值而返回 null 值,而不是表示该列的小计(此null非分组null)

5.grouping__id函数

–grouping__id 函数返回一个整数值。该值对应于位向量的十进制解释,该向量由串联的 1 和 0 组成,将由一系列 grouping 函数按从左到右的顺序返回,这与 grouping__id 函数中指定参数的顺序相同。二进制

selectnvl(empid, '订单平均') empid,custid,avg(qty),grouping__id
from orders
group by empid,custid
grouping sets(empid, custid);

selectnvl(empid, '订单平均') empid,custid,avg(qty),if(grouping__id = 1, '员工平均', '顾客平均')
from orders
group by empid,custid
grouping sets(empid, custid);

–二进制

selectyear(orderdate) orderyear,month(orderdate) ordermonth,sum(qty) sum_qty,grouping(year(orderdate)) g_y,grouping(year(orderdate), month(orderdate)) g_ym,grouping__id gid
from Orders
group by year(orderdate),month(orderdate)
grouping sets ( year(orderdate), (year(orderdate), month(orderdate)), () );

–好理解

selectnvl(empid, '订单平均') empid,custid,avg(qty),grouping(empid) g_e,grouping(custid) g_c,grouping__id gid
from orders
group by empid,custid
grouping sets(empid, custid);

–在hive里grouping__id不能放参数,oral可以

6.grouping__sets多维度组合去重统计避免使用distinct

–通过grouping sets和distinct进行统计

selectgrouping__id g_id,year(orderdate) orderyear,month(orderdate) ordermonth,sum(qty) sum_qty,count(distinct empid) dis_empid
from Orders
group by year(orderdate),month(orderdate)
grouping sets ( year(orderdate),  (year(orderdate), month(orderdate)) );

–通过grouping sets将empid加入维度组合再进行group by统计

select g_id, orderyear, ordermonth, sum(sum_qty), count(1) dis_empidfrom (selectcast(grouping__id as int)&7 g_id,--可以让grouping__id好看点year(orderdate) orderyear,month(orderdate) ordermonth,sum(qty) sum_qty,empidfrom Ordersgroup by year(orderdate),month(orderdate),empid grouping sets ( (year(orderdate),empid),  (year(orderdate), month(orderdate),empid) )) tgroup by g_id, orderyear, ordermonth;

–在hive没有group by all----sql或olap有

selectempid,sum(qty) sum_qty
from orders
where empid=2
group by all empid;

hive grouping sets多维度报错

如果你的 grouping sets大于等于5个维度,将会报如上的错误;解决办法:

An additional MR job is introduced since the cardinality of grouping sets is more than hive.new.job.grouping.set.cardinality. This functionality is not supported with distincts. Either set hive.new.job.grouping.set.cardinality to a high number (higher than the number of rows per input row due to grouping sets in the query), or rewrite the query to not use distincts. The number of rows per input row due to grouping sets is 32
  1. 在你的hql语句前面加上 set hive.new.job.grouping.set.cardinality=xx;(例如我这里是5个维度,一共32个grouping sets,xx我写的64 )
  2. 可以通过在子查询中用group by去重,避免在聚合中用到distinct

hive中grouping sets 数量较多时,可以使用如下设置来:set hive.new.job.grouping.set.cardinality = 30;这条设置的意义在于告知解释器,group by之前,每条数据复制量在30份以内。

当维度过高,且统计语句中使用了 count distinct语句,就有可能出现如下报错

- Error while compiling statement: FAILED: SemanticException [Error 10226]: An additional MR job is introduced since the cardinality of grouping sets is more than hive.new.job.grouping.set.cardinality. This functionality is not supported with distincts. Either set hive.new.job.grouping.set.cardinality to a high number (higher than the number of rows per input row due to grouping sets in the query), or rewrite the query to not use distincts. The number of rows per input row due to grouping sets is 256

此时可以通过以下语句突破这个限制set hive.new.job.grouping.set.cardinality = 256;

其中256 为可以调节的数字,一般这个数字要大于你的维度的最高值,但是切记要慎用,一般维度最好不要超过7维,否则对集群压力会比较大

grouping sets函数相关推荐

  1. 【Hive】grouping sets() 函数

    文章目录 1. 语法 2. 例子 1. 语法 grouping sets()函数是一种将多个group by逻辑写在一个sql语句中的便利写法. 等价于将不同维度的GROUP BY结果集进行UNION ...

  2. oracle 分组统计效率,Oracle 分组求和函数(rollup、cube、grouping sets)

    文章目录 1 场景 1.1 概念 1.2 思维导图 1.3 数据准备 2 知识点小结 2.1 group by 2.2 grouping sets:单独分组 2.3 rollup:累计累加 2.4 c ...

  3. presto和hive中grouping sets的格式不一致问题

    背景 遇到的问题,在presto中使用hive中的grouping sets报错 报错信息如下 [1] Query failed (#20220811_003524_00009_hzxre): lin ...

  4. Hive之grouping sets用法详解

    目录 关键字: 简单示例: 实例一: presto中grouping sets函数 关键字: GROUPING SETS: 根据不同的维度组合进行聚合,等价于将不同维度的GROUP BY结果集进行UN ...

  5. [转]详解Oracle高级分组函数(ROLLUP, CUBE, GROUPING SETS)

    原文地址:http://blog.csdn.net/u014558001/article/details/42387929 本文主要讲解 ROLLUP, CUBE, GROUPING SETS的主要用 ...

  6. Hive函数:GROUPING SETS,GROUPING__ID,CUBE,ROLLUP

    参考:lxw大数据田地:http://lxw1234.com/archives/2015/04/193.htm 数据准备: CREATE EXTERNAL TABLE test_data ( mont ...

  7. Hive sql分组函数grouping sets、cube、rollup用法简介

    文章目录 1.数据如下: 2.建表如下: 3.grouping sets 4.cube 5.rollup 1.数据如下: user_id,dep_id,group_id,salary 10001,a, ...

  8. T-SQL中的GROUP BY GROUPING SETS

    最近遇到一个情况,需要在内网系统中出一个统计报表.需要根据不同条件使用多个group by语句.需要将所有聚合的数据进行UNION操作来完成不同维度的统计查看. 直到发现在SQL SERVER 200 ...

  9. Hive分析窗口函数(五) GROUPING SETS,GROUPING__ID,CUBE,ROLLUP

    GROUPING SETS 该关键字可以实现同一数据集的多重group by操作.事实上GROUPING SETS是多个GROUP BY进行UNION ALL操作的简单表达,它仅仅使用一个stage完 ...

最新文章

  1. Opencv 基础 MatOfByte创建和byte数组
  2. Invalid indirect reference 0x28 in decodeIndirectR
  3. Swift中使用构建配置来支持条件编译-b
  4. 【工具使用系列】关于 MATLAB 有限元分析,你需要知道的事
  5. 大事件后台管理系统开发实战(下)
  6. 亚马逊出的平板电脑_美国最畅销的安卓平板电脑,还只有2GB内存
  7. 【Python】time内置模块处理时间信息
  8. Hash魔法:分布式哈希算法
  9. html广告清理,谷歌浏览器插件-清除CSDN广告
  10. 完结!视频课程:CMOS模拟集成电路设计
  11. mysql读写分离延迟_解决Mysql读写分离数据延迟
  12. ipv6文件服务器,ipv6怎么配置服务器
  13. 管家婆财贸双全ⅡTOP 期间202012的损益类科目本币(外币或者数量)余额不为零,不能年结存。
  14. Win7怎么开启或关闭dep数据执行保护
  15. Google Guava简介
  16. 蓝桥杯 算法训练 跳马
  17. java区分无线网卡,无线网卡种类有什么区别
  18. javaweb基于内容的图片搜索(2)_java爬虫
  19. mac系统ssh可视化工具zoc的简单使用
  20. 今天不谈技术,说说一些常用的软件~By 逆天

热门文章

  1. busybox的下载、配置、编译、安装一条龙服务
  2. 银河麒麟下安装sshd服务(联网)
  3. java word转pdf linux_java实现word转pdf在线预览(前端使用PDF.js;后端使用openoffice、aspose)...
  4. 【原创】java使用gamil发信
  5. 什么是浅拷贝和深拷贝
  6. 7.1 模板方法模式 (Template Pattern)
  7. Unity使用MatchVS联网
  8. Java50道经典编程题:(十八)兵乓球赛程安排问题 ——对知识的灵活使用
  9. 基于php+thinkphp+vue养生馆保健品购物商城网站(源码+系统+mysql数据库+Lw文档)
  10. spark入门【大数据spark】