关于SQL中GROUPING()函数在ROLLUP分组下的取值疑问
搞懂ROLLUP搭配GROUPING函数的逻辑:为什么会出现3和7?
嘿,我来帮你拆解这个问题,你看到的3和7其实是二进制位掩码转成的十进制数,咱们一步步理清楚:
先明白ROLLUP的作用
你用的ROLLUP(t_year, t_quarter, t_month)会自动生成不同层级的汇总行,从最细粒度到最高层级:
- 第一级:按
年+季度+月份分组(最细的明细行) - 第二级:按
年+季度分组,汇总该季度下所有月份的数据 - 第三级:按
年分组,汇总该年份下所有季度的数据 - 第四级:汇总整个筛选范围(这里是2016年全年)的所有数据
再看GROUPING函数的工作原理
GROUPING()函数的本质是生成一个位掩码:
- 它接受的每个参数对应一个二进制位,参数顺序从左到右,对应二进制的高位到低位(权重分别是
2²=4、2¹=2、2⁰=1,因为你有3个参数) - 如果某一列在当前行是被ROLLUP聚合掉的(也就是该行没有该列的具体值,是汇总结果),对应的二进制位就设为
1;如果列有具体值,就设为0 - 最后把这个二进制数转换成十进制,就是你看到的
date_level_year_quarter_month的值
对应到你的结果中的3和7
咱们逐个对应:
值为3的行:这是按
年汇总的行(比如t_year=2016,t_quarter和t_month都是NULL)t_year有具体值,对应位0;t_quarter和t_month被聚合,对应位都是1- 二进制是
011,转换成十进制:0*4 + 1*2 + 1*1 = 3
值为7的行:这是全量汇总的行(三个字段都是NULL,对应2016年全年的总汇总)
t_year、t_quarter、t_month都被聚合,三个位都是1- 二进制是
111,转换成十进制:1*4 + 1*2 + 1*1 = 7
验证小技巧
如果你想更直观地看每个列的位状态,可以把GROUPING拆成单独的列:
SELECT t_year, t_quarter, t_month, GROUPING(t_year) AS g_year, GROUPING(t_quarter) AS g_quarter, GROUPING(t_month) AS g_month, GROUPING(t_year, t_quarter, t_month) AS date_level FROM d_time WHERE t_year IN (2016) GROUP BY ROLLUP(t_year, t_quarter, t_month) ORDER BY 1, 2, 3;
运行后你能清楚看到每个列对应的0或1,按权重相加就是最终的date_level值,完全能对应上你看到的结果~
内容的提问来源于stack exchange,提问作者Janna Sherazi
相关产品推荐
相关产品推荐

