前言
今日翻看项目之前某模块的代码时,看到grouping_id的sql语句。一时忘记了这个函数的用法,遂赶紧写下这篇以防日后在用到时能快速想起其用法。
背景
我们在项目中使用到grouping_id函数的场景是这样的,客户投放的广告是有各种维度信息的,那么客户想要组合这些不同的维度去查看广告带来的一些统计信息。那么对于历史的数据,我们是直接将所有的维度组合,统计所有指标然后将结果存储。由于不确定客户想看哪些维度的组合数据,所以就需要将所有维度的组合统计指标都计算出来,这时候grouping_id这个函数进入了我们的视线。
GROUPING_ID用法
对于GROUPING_ID函数的用法在不同的框架中是大同小异的,就以spark sql为例。直接上代码更直观理解用法
session.sparkContext.parallelize(Seq((1,"a"),(2,"b"),(3,"c"))).toDF("id","name").createOrReplaceTempView("test")
session.sql(
s"""
|SELECT id,name
|FROM test
""".stripMargin).show()
session.sql(
s"""
|SELECT id,name,GROUPING__ID
|FROM test
|GROUP BY id,name WITH ROLLUP
""".stripMargin).show()
session.sql(
s"""
|SELECT id,name,GROUPING__ID
|FROM test
|GROUP BY id,name WITH CUBE
""".stripMargin).show()
// 执行结果
+---+----+
| id|name|
+---+----+
| 1| a|
| 2| b|
| 3| c|
+---+----+
+----+----+------------+
| id|name|grouping__id|
+----+----+------------+
| 3|null| 1|
| 1|null| 1|
|null|null| 3|
| 2|null| 1|
| 3| c| 0|
| 2| b| 0|
| 1| a| 0|
+----+----+------------+
+----+----+------------+
| id|name|grouping__id|
+----+----+------------+
| 3|null| 1|
|null| b| 2|
|null| c| 2|
| 1|null| 1|
|null|null| 3|
|null| a| 2|
| 2|null| 1|
| 3| c| 0|
| 2| b| 0|
| 1| a| 0|
+----+----+------------+
上述代码直接带上了WITH ROLLUP和WITH CUBE的对比。第三个的结果是WITH CUBE的,他的意思就是将你GROUP BY的字段进行笛卡尔组合,而grouping__id是一个可以认为是标识的字段,他表示某个字段是否参与了组合,用二进制表示就是如果字段参与了组合就是0,否则是1,靠近group by的字段是低位。组合后十进制数就是grouping__id的值。所以我们可以通过grouping__id倒推出某条数据哪些字段被组合了。ROLLUP的计算逻辑是一样的,区别就是ROLLUP只将靠近group by的字段跟后边的字段有值和null组合。三个字段以上首尾中间的字段不会有null。
hive和spark中GROUPING_ID的区别
hive中GROUPING_ID的用法跟上边spark是一样的,不同之处有两个地方
1.hive中靠近group by的字段是高位,倒推grouping__id数值的时候需要注意
2.hive中参与了组合的字段是1,未参与是0
结束
文章简单介绍了GROUPING_ID函数的使用,希望对刚接触的小伙伴有点作用。
欢迎对技术感兴趣的小伙伴一起交流学习,批评指正^^