如何在select语句中使用分组集的分组子句?

时间:2013-05-09 13:27:56

标签: sql sql-server-2005 grouping hierarchy

我刚刚学会了使用grouping sets子句,我相信我可以重写一个旧的查询。目前,它是来自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)
...

1 个答案:

答案 0 :(得分:0)

如果包含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