grouping sets
如果说聚合函数(Simple UDAF / Generic UDAF)是HQL聚合数据查询或分析的中枢处理器,那GROUP BY可以说是聚合函数的神经了,GROUP BY收集和传递材料,然后交给聚合函数们去处理。这些材料的组织形式显得尤为重要,它们表达着分析者想要的观察维度或视角,管理着聚合函数们的操作对象。
而分析者经常想要在一次分析中从多个维度去获得分析数据,对包含多个维度或多级层次的分析,上卷(roll up)或下钻(drill down)一类就很有分析价值。
我们有时候可以从最细、最多的粒度去做一个查询,然后把结果集导入Excel这个数据分析利器,用数据透视图标进行“上卷”分析;但有时候也行不通,比如说UV这种需要去重的数据,在Excel里用汇总方式进行上卷,就不是纯粹的UV概念了。
所以,对这种情形,在查询过程中,我们就需要获得已经下钻和上卷的数据;如果只有GROUP BY子句,那我们可以写出按各个维度或层次进行GROUP BY的查询语句,然后再通过UNION子句把结果集拼凑起来,但是这样的查询语句显得冗长、笨拙。
为此,HQL像其它很多SQL实现一样,为我们提供了GROUPINGSETS子句来简化查询语句的编写,以下官方CWiki文档很清晰地表达了GROUPING SETS的功能:
Aggregate Query with GROUPING SETS | Equivalent Aggregate Query with GROUP BY |
SELECT a, b, SUM(c) FROM tab1 GROUP BY a, b GROUPING SETS ( (a,b) ) | SELECT a, b, SUM(c) FROM tab1 GROUP BY a, b |
SELECT a, b, SUM( c ) FROM tab1 GROUP BY a, b GROUPING SETS ( (a,b), a) |
SELECT a, b, SUM( c ) FROM tab1 GROUP BY a, b UNION SELECT a, null, SUM( c ) FROM tab1 GROUP BY a |
SELECT a,b, SUM( c ) FROM tab1 GROUP BY a, b GROUPING SETS (a,b) |
SELECT a, null, SUM( c ) FROM tab1 GROUP BY a UNION SELECT null, b, SUM( c ) FROM tab1 GROUP BY b |
SELECT a, b, SUM( c ) FROM tab1 GROUP BY a, b GROUPING SETS ( (a, b), a, b, ( ) ) |
SELECT a, b, SUM( c ) FROM tab1 GROUP BY a, b UNION SELECT a, null, SUM( c ) FROM tab1 GROUP BY a, null UNION SELECT null, b, SUM( c ) FROM tab1 GROUP BY null, b UNION SELECT null, null, SUM( c ) FROM tab1 |
因为涉及UNION操作,所以为了遵循UNION对参与合并的数据集合的要求,GROUPING SETS会把在单个GROUP BY逻辑中没有参与GROUP BY的那一列置为NULL值,使它成为常量占位列。这样聚合出来的结果,未被GROUP BY的列将显示为NULL。
但是这样的处理也会引起一个歧义性问题,如果我们分析的表有一些列没有NOT NULL约束,那原始数据中,未被GROUP BY的列可能原本就会出现一些NULL值,这样,GROUPING SETS出来的结果,我们没有办法去区分该列显示的NULL值是原始数据出现的NULL值聚合的结果,还是你因为这列没有参与GROUP BY而被置为NULL值的结果。
为了解决这个歧义问题,HQL又为我们提供了一个Grouping__ID函数(请注意函数名中的下划线是两个!);这个函数没有参数,在有GROUPING SETS子句的情况下,把它直接放在SELECT子句中,像其它列一样,独占一列。它返回的结果是一个看起来像整形数值类型,其实是字符串的值,这个值使用了位图策略(bitvector,位向量),即它的二进制形式中的每1位标示着对应列是否参与GROUP BY,如果某一列参与了GROUP BY,对应位就被置为1,否则为0,根据这个位向量值和对应列是否显示为NULL,我们就可以解决上面提到的歧义问题了。
这样一来,Grouping__ID函数返回值的范围由查询的字段数(除去聚合函数产生的列)决定,如果比如有3列,那位向量为3位,最大值为7。CWiki文档提供了下面的示例:
有下面一个表数据:
我们用这样的查询语句去执行查询:
SELECT key, value, GROUPING__ID, count(*) from T1 GROUP BY key,value WITH ROLLUP
得到如下结果:
官方文档没有明确说明这个位向量和各列的高低位对应关系,但是从示例我们可以看到,这个位向量的低位对应SELECT子句中的第1列(非聚合列),高位对应最后1列(非聚合列)。
上面的查询用到了WITH ROLLUP子句,它对应SQL中的上卷操作,其实它就是GROUPINGSETS的特例,对应上面第一个表格中的第4种情形;根据官方的CWiki文档解释,GROUP BY 子句加上ROLLUP 子句可用于计算从一个维度进行层级聚合的操作:
GROUP BY a, b, c with ROLLUP assumes that the hierarchy is"a" drilling down to "b" drilling down to "c".
类似地还有WITH CUBE子句,对应SQL中的CUBE操作,它完成对字段列中的所有可能组合(全序集?)进行GROUP BY的功能,正如官方CWiki文档的解释:
GROUP BY a, b, c WITH CUBE 等同于
GROUP BY a, b, c GROUPING SETS ( (a, b, c), (a, b), (b, c), (a, c),(a), (b), (c), ( ))
GROUPING SETS增强了GROUP BY的查询表达能力,ROLLUP和CUBE又增强了GROUPING SETS的查询表达能力,这样一来,GROUP BY的形态也变得多样化了,让我们能够在查询阶段就实现更多的分析角度。
还需留意的是:Hive从0.10.0版本才开始有GROUPING SETS的。
官方CWiki文档请点我:https://cwiki.apache.org/confluence/display/Hive/Enhanced+Aggregation,+Cube,+Grouping+and+Rollup
grouping sets相关推荐
- SQL Server里Grouping Sets的威力
在SQL Server里,你有没有想进行跨越多个列/纬度的聚集操作,不使用SSAS许可(SQL Server分析服务).我不是说在生产里使用开发版,也不是说安装盗版SQL Server. 不可能的任务 ...
- [转]详解Oracle高级分组函数(ROLLUP, CUBE, GROUPING SETS)
原文地址:http://blog.csdn.net/u014558001/article/details/42387929 本文主要讲解 ROLLUP, CUBE, GROUPING SETS的主要用 ...
- T-SQL中的GROUP BY GROUPING SETS
最近遇到一个情况,需要在内网系统中出一个统计报表.需要根据不同条件使用多个group by语句.需要将所有聚合的数据进行UNION操作来完成不同维度的统计查看. 直到发现在SQL SERVER 200 ...
- oracle group by 两项,Oracle中group by 的扩展函数rollup、cube、grouping sets
Oracle的group by除了基本使用方法以外,还有3种扩展使用方法,各自是rollup.cube.grouping sets.分别介绍例如以下: 1.rollup 对数据库表emp.如果当中两个 ...
- Hive分析窗口函数(五) GROUPING SETS,GROUPING__ID,CUBE,ROLLUP
GROUPING SETS 该关键字可以实现同一数据集的多重group by操作.事实上GROUPING SETS是多个GROUP BY进行UNION ALL操作的简单表达,它仅仅使用一个stage完 ...
- Hive函数:GROUPING SETS,GROUPING__ID,CUBE,ROLLUP
参考:lxw大数据田地:http://lxw1234.com/archives/2015/04/193.htm 数据准备: CREATE EXTERNAL TABLE test_data ( mont ...
- mysql group by cube_SQL Server 之 GROUP BY、GROUPING SETS、ROLLUP、CUBE
1.创建表 Staff CREATE TABLE [dbo].[Staff]([ID] [int] IDENTITY(1,1) NOT NULL,[Name] [varchar](50) NULL,[ ...
- GROUPING amp; GROUPING_ID amp; GROUP_ID amp; GROUPING SETS
一.grouping() 函数必须接受一列且只能接受一列做为其参数.参数列值为空返回1,参数列值非空返回0. 二.grouping_id()函数 GROUPING_ID可以接收多个列,返回值为按参数排 ...
- postgresql 集合类型_PostgreSQL 分组集合新功能(GROUPING SETS,CUBE,ROLLUP)
PostgreSQL 分组集合新功能(GROUPING SETS,CUBE,ROLLUP) 实验环境 操作系统:windows 10 家庭中文版 数据库系统: PostgreSQL 9.6.2 说明 ...
- mysql group by cube_SparkSQL 中group by、grouping sets、rollup和cube方法详解
在平时的工作中,经常有按照不同维度筛选和统计数据的需求.拿视频会员订单数据来说吧,运营人员要查看深圳市的成功下单数或则深圳市某一种产品的成功下单数或者某一种产品的所有成功下单数时,每天的订单数又很大, ...
最新文章
- 《OpenCV3编程入门》学习笔记9 直方图与匹配(五)模板匹配
- matlab练习程序(高斯牛顿法最优化)
- tomcat8.0.15+spring4.1.2的集群下共享WebSocketSession?
- 网络推广计划浅析如何增加网站蜘蛛的爬取频次?
- fastjson异常问题
- 第二章 数组名是一个指针常量吗?
- mongodb输错命令后不能删除问题
- 【机器学习】集成学习之梯度提升树GBDT
- 光伏“转化效率之王”IBC电池有多牛?
- python+ UIAutomator2+WEditor环境安装详情教学以及案例
- 常用web前端UI组件库
- XCELSIUS例子(CX钻取).
- android三星s8底部菜单,【Android】三星Galaxy S8及S8+的屏幕适配
- C#编写一个简单串口通讯上位机
- ACM纪念日 C语言
- SpringBoot之使用Security
- python入门第三课(初中生学Python)
- kotlin用it还是this?
- DHCP 和 DHCP-Realy 功能演示完整示例
- 【毕业设计源码】基于Python的校园生活助手(二手+活动+论坛+新闻)信息系统