【问题标题】:How do I use the grouping clause in my select statement with grouping sets?如何在带有分组集的 select 语句中使用分组子句?
【发布时间】:2013-05-14 23:45:47
【问题描述】:

我刚刚学会了使用分组集子句,我相信我可以重写我的一个旧查询。目前,它是来自 CTE 的 5 个不同分组的联合。我知道我应该能够轻松地将其更改为通过偶数汇总的分组集分组到的不同层次结构,但我需要在每个级别或分组上指定一个文字。我无法向您展示我的实际代码,但下面有一个示例。

select 
    b.LEVEL_ONE, b.LEVEL_TWO, b.LEVEL_THREE, b.LEVEL_FOUR, b.LEVEL_FIVE,
    case
        when (grouping(b.LEVEL_FIVE)=1) then ''
        when ...
        when ...
        when ...
        when ...
        when ...
    end as'LEVEL_TYPE',
    sum(b.VALUE) as TOTAL
from
    BASE b
where
    ...
group by GROUPING SETS(
    (b.LEVEL_ONE, b.LEVEL_TWO, b.LEVEL_THREE, b.LEVEL_FOUR, b.LEVEL_FIVE),
    (b.LEVEL_ONE, b.LEVEL_TWO, b.LEVEL_THREE, b.LEVEL_FOUR),
    (b.LEVEL_ONE, b.LEVEL_TWO, b.LEVEL_THREE),
    (b.LEVEL_ONE, b.LEVEL_TWO, b.LEVEL_FOUR),
    (b.LEVEL_ONE, b.LEVEL_TWO),
    (b.LEVEL_ONE, b.LEVEL_TWO)
)

这只是我想我想去的地方的一般概念。我遇到的问题是当我使用第 3 组或第 4 组时如何指定文字。有什么想法吗?

编辑:

预期结果是如下所示的行:

LEVEL_ONE | LEVEL_TWO | LEVEL_THREE | LEVEL_FOUR | LEVEL_FIVE | LEVEL_TYPE | TOTAL

'lvl1'    | 'lvl2'    | 'lvl3'      | 'lvl4'     | 'lvl5'     | 'LEVEL 5'  | (int)
...
'lvl1'    | 'lvl2'    | 'lvl3'      | 'lvl4'     | null       | 'LEVEL 3,4'| (int)
...
'lvl1'    | 'lvl2'    | null       | 'lvl4'     | null       | 'LEVEL 4'  | (int)
...
'lvl1'    | 'lvl2'    | 'lvl3'      | null       | null       | 'LEVEL 3'  | (int)
...
'lvl1'    | 'lvl2'    | null       | null       | null       | 'LEVEL 2'  | (int)
...
'lvl1'    | null      | null        | null       | null       | 'LEVEL 1'  | (int)
...

【问题讨论】:

  • 什么是 RDBMS(SQL 风格)?您能否为您的示例提供示例数据和预期结果?
  • SQL Server 2005。示例数据不可用。我实例中的字段只是整数。将包括预期结果。
  • 对不起,如果这是一个愚蠢的问题,但为什么 (b.LEVEL_ONE, b.LEVEL_TWO) 项目指定了两次?实际上,根据您的预期输出,我认为您在那里犯了一个错误,第二个条目应该只是(b.LEVEL_ONE)
  • 是的。本来应该是这样的,但问题已经结束,没有任何区别。

标签: sql sql-server-2005 grouping hierarchy


【解决方案1】:

如果您包含 SQL DDL 和示例数据,您将获得更多更好的答案。以下代码未经测试。

为了更好地了解发生了什么,请为每个分组集添加一列。

select 
    b.LEVEL_ONE, b.LEVEL_TWO, b.LEVEL_THREE, b.LEVEL_FOUR, b.LEVEL_FIVE,
    grouping(LEVEL_ONE)   grp_lvl1,
    grouping(LEVEL_TWO)   grp_lvl2,
    grouping(LEVEL_THREE) grp_lvl3,
    grouping(LEVEL_FOUR)  grp_lvl4,
    grouping(LEVEL_FIVE)  grp_lvl5,
    sum(b.VALUE) as TOTAL
from
    BASE b
where
    ...
group by GROUPING SETS(
    (b.LEVEL_ONE, b.LEVEL_TWO, b.LEVEL_THREE, b.LEVEL_FOUR, b.LEVEL_FIVE),
    (b.LEVEL_ONE, b.LEVEL_TWO, b.LEVEL_THREE, b.LEVEL_FOUR),
    (b.LEVEL_ONE, b.LEVEL_TWO, b.LEVEL_THREE),
    (b.LEVEL_ONE, b.LEVEL_TWO, b.LEVEL_FOUR),
    (b.LEVEL_ONE, b.LEVEL_TWO),
    (b.LEVEL_ONE, b.LEVEL_TWO)
);

我不确定你编写的分组集是否真的是你想要的。仔细观察它们。

检查该查询的输出后,您将能够了解如何构建 CASE...WHEN 表达式。它可能最终会看起来像这样

(case when (grouping(LEVEL_ONE)   = 1) and
           (grouping(LEVEL_TWO)   = 1) and
           (grouping(LEVEL_THREE) = 1) and 
           (grouping(LEVEL_FOUR)  = 1) and 
           (grouping(LEVEL_FIVE)  = 1) then 'Some string literal here'
      when (grouping(LEVEL_ONE)   = 0) and
           (grouping(LEVEL_TWO)   = 1) and
           (grouping(LEVEL_THREE) = 1) and 
           (grouping(LEVEL_FOUR)  = 1) and 
           (grouping(LEVEL_FIVE)  = 1) then 'Some other string literal here'
      when ...
 end) LEVEL_TYPE

【讨论】:

  • 对。这就是我最终通过首先研究 grouping() 子句的输出然后重新排列正确组合的值来解决它的方法。
猜你喜欢
  • 1970-01-01
  • 2018-08-31
  • 2021-12-12
  • 2013-07-07
  • 2011-09-17
  • 1970-01-01
  • 2012-11-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多