GROUPING SETS特殊用法之grouping__id

文章介绍了在SQL中使用GROUPINGSETS和grouping__id进行多级商品类目汇总的方法。由于不能使用rollup和cube来避免‘全部’ID和名称不匹配的问题,文章详细解释了如何利用grouping__id的按位运算特性,根据不同的二进制位判断是否显示全部,以保证各级类目信息的同步。

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

GROUPING SETS用法之grouping__id

场景描述

根据月份,多级商品类目(包括id 和 对应的名称) 汇总商品数

当前场景使用不了 rollup 以及 cube ,原因是这里有同级商品类别的id和name,需要保持同步,如果使用cube或者rollup,''
则会出现id,'全部' 或者 '全部',id 的情况出现,但是用grouping__id可以避免这种情况的发生

具体sql代码 及 代码解析


具体的sql:
SELECT 
     IF(GROUPING__ID & 4 = 4, 'ALL' ,lv3_goods_id)           AS  lv3_goods_id  
    ,IF(GROUPING__ID & 4 = 4, '全部',MAX(lv3_goods_name))    AS  lv3_goods_name
    ,IF(GROUPING__ID & 2 = 2, 'ALL' ,lv2_goods_id)           AS  lv2_goods_id  
    ,IF(GROUPING__ID & 2 = 2, '全部',MAX(lv2_goods_name))    AS  lv2_goods_name
    ,IF(GROUPING__ID & 1 = 1, 'ALL' ,lv1_goods_id)           AS  lv1_goods_id  
    ,IF(GROUPING__ID & 1 = 1, '全部',MAX(lv1_goods_name))    AS  lv1_goods_name
    ,count(distinct lv4_goods_id) as lv4_goods_num 
FROM 
    (
    SELECT
         lv1_goods_id
        ,lv1_goods_name
        ,lv2_goods_id
        ,lv2_goods_name
        ,lv3_goods_id
        ,lv3_goods_name
        ,lv4_goods_id
    FROM database.goods_info
    ) t1
GROUP BY 
 lv3_goods_id
,lv2_goods_id
,lv1_goods_id
     GROUPING SETS
     (
         (lv1_goods_id)   
        ,(lv1_goods_id,lv2_goods_id)
        ,(lv1_goods_id,lv2_goods_id,lv3_goods_id)
		,()
     ) 

-------------------------------------- 代码解析 --------------------------------------
4的二进制
0000 0100


-- 跟下面的group by 的字段位置有关
 GROUP BY   
     lv3_goods_id   
    ,lv2_goods_id
    ,lv1_goods_id
      GROUPING SETS
      (
         (lv1_goods_id)   
        ,(lv1_goods_id,lv2_goods_id)
        ,(lv1_goods_id,lv2_goods_id,lv3_goods_id)
	,()
      ) 
		 
		 
四种分组对应的二进制  按位取反  取反后的二进制  我认为取反之后 为1的这个位置是汇总列,所以只有这一列为1,那么就是对应的全部,所以采用按位与的方式
001                   ==>                        110
011                   ==>                        100
111                   ==>                        000
000	              ==>                        111


-- 对于下面的判断
 ,IF(GROUPING__ID & 4 = 4, 'ALL' ,lv3_goods_id)           AS  lv3_goods_id  
 ,IF(GROUPING__ID & 4 = 4, '全部',MAX(lv3_goods_name))    AS  lv3_goods_name
 ,IF(GROUPING__ID & 2 = 2, 'ALL' ,lv2_goods_id)           AS  lv2_goods_id  
 ,IF(GROUPING__ID & 2 = 2, '全部',MAX(lv2_goods_name))    AS  lv2_goods_name
 ,IF(GROUPING__ID & 1 = 1, 'ALL' ,lv1_goods_id)           AS  lv1_goods_id  
 ,IF(GROUPING__ID & 1 = 1, '全部',MAX(lv1_goods_name))    AS  lv1_goods_name
		
		
-- 举例说明 GROUPING__ID & 4 = 4 
4的二进制是 0000 0100 

GROUPING__ID & 4 = 4 

下面四种 按位与 4 后 等于 0000 0100 的组合是    (lv1_goods_id),(lv1_goods_id,lv2_goods_id),()         
0110
0100
0111

即对一级,一级+二级,全部汇总 三种角度去汇总数据时,三级类目使用 "全部" 表示

在这里插入图片描述

### HiveGrouping Sets用法 #### 基本概念 Grouping Sets 是一种在 Hive 查询中简化多维分组操作的功能。通过使用 `GROUPING SETS`,可以在一条 SQL 语句中实现多个不同维度的聚合逻辑,从而减少多次执行查询的需求[^1]。 #### 语法结构 以下是 `GROUPING SETS` 的基本语法: ```sql SELECT column_list, aggregate_function(column) FROM table_name GROUP BY GROUPING SETS ( (column_set_1), (column_set_2), ... ); ``` 其中: - `column_list`: 需要展示的结果列。 - `aggregate_function`: 聚合函数(如 `SUM`, `AVG`, `COUNT` 等)。 - `(column_set_n)`: 表示一组或多组需要进行分组的列集合。 #### 示例解析 假设有一个表名为 `tableName`,其字段包括 `class`(班级)、`sex`(性别)、`course`(课程)以及 `score`(分数)。我们希望按不同的维度组合来统计平均成绩。 创建临时表存储结果数据: ```sql CREATE TABLE temp.score_grouping AS SELECT grouping__id, class, sex, course, AVG(score) AS avg_score FROM tableName GROUP BY class, sex, course GROUPING SETS ( (class, course), (class, sex), (sex, course), (course) ); ``` 上述代码实现了以下几种分组方式: - 按照 `class` 和 `course` 组合分组; - 按照 `class` 和 `sex` 组合分组; - 按照 `sex` 和 `course` 组合分组; - 单独按照 `course` 分组; 最终结果可以通过查看 `temp.score_grouping` 表获得。对于某些未参与特定分组的字段,在对应记录中会显示为 NULL 值[^3]。 #### 特殊字段 `grouping__id` 当使用 `GROUPING SETS` 时,Hive 自动生成了一个特殊字段 `grouping__id` 来表示当前行属于哪个具体的分组设置。该值是一个整数编码形式,能够帮助区分每条记录来源于哪种分组模式。 例如过滤部分类型的分组结果: ```sql SELECT * FROM temp.score_grouping WHERE grouping__id IN ('2', '6'); ``` 此命令仅返回那些满足条件编号下的汇总信息。 #### 扩展功能 除了 `GROUPING SETS` 外,Hive 提供了其他类似的高级聚合工具,比如 CUBE 和 ROLLUP,它们分别代表全排列交叉分组与逐层累加式的层次化分组[^2]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值