为何GROUPING SETS中的()无法生成总计?SQL分组查询疑问
为什么GROUPING SETS的()没生成预期的总计行
核心原因
你用ISNULL([BusinessType], 'TOTAL')标记总计行的方式存在问题,无法区分原数据中的NULL值和GROUPING SETS生成的总计行NULL值,甚至可能因为结果排序导致你忽略了总计行。
问题拆解
GROUPING SETS (BusinessType, ())的逻辑是完全正确的,它会生成两组结果:
- 一组按
BusinessType分组的聚合行 - 一组不分组的总计行(此时
BusinessType列值为NULL)
但ISNULL会把所有NULL值(不管是原数据的还是总计行的)都替换成TOTAL,这就会导致两种混淆:
- 如果原表中
BusinessType本身存在NULL,你会看到两行TOTAL(一行是原NULL的分组,一行是总计),容易误以为只有原分组行 - 如果原表中没有
NULL,总计行确实存在,但可能因为排序在结果中间,你没注意到
正确的写法
用GROUPING函数识别总计行,这个函数专门用来判断当前列是否是GROUPING SETS中被忽略的列(总计行时返回1,正常分组返回0):
SELECT CASE WHEN GROUPING([BusinessType]) = 1 THEN 'TOTAL' ELSE [BusinessType] END AS [BusinessType] ,COUNT(DISTINCT CONCAT([ProductLine], BankName)) AS DistinctCombinationCount FROM [AdventureWorksDW2019].[dbo].[DimReseller] GROUP BY GROUPING SETS (BusinessType, () )
验证总计行是否存在
如果你不确定总计行是否真的生成,可以先执行以下SQL查看原始结果:
SELECT [BusinessType] ,GROUPING([BusinessType]) AS IsTotalRow -- 1表示是总计行,0表示普通分组行 ,COUNT(DISTINCT CONCAT([ProductLine], BankName)) AS DistinctCombinationCount FROM [AdventureWorksDW2019].[dbo].[DimReseller] GROUP BY GROUPING SETS (BusinessType, () )
执行后,IsTotalRow为1的那一行就是你要的总计行,此时BusinessType为NULL。
内容的提问来源于stack exchange,提问作者mikey22022
相关产品推荐
相关产品推荐

