复杂的多行聚合SQL查询

时间:2013-03-30 23:48:15

标签: sql db2 aggregate-functions

我正在寻找一种通过在多行中存在相同外键来聚合的方法。

例如,ID号1和2应该聚合在一起,因为它们在所有行中都具有相同的确切外键,而ID号3在所有行中没有相同的外键,因此它应该是分开的。

注意:使用DB2

示例源数据:

ID  QUANTITY    COLOR
1   10          BLUE
1   10          RED
1   10          GREEN
2   30          BLUE
2   30          RED
2   30          GREEN
3   15          GREEN
3   15          YELLOW

期望的结果集:

TEMP_ID     SUMQTY  COLOR
1           40      BLUE
1           40      RED
1           40      GREEN
2           15      GREEN
2           15      YELLOW

1 个答案:

答案 0 :(得分:1)

首先,我们需要找出两个“ID”的“颜色”是否相同。以下查询在color上执行完全外部联接,然后按id进行聚合。如果两个id具有相同的颜色,则完整的外部连接始终匹配 - 没有NULL:

select s1.id, s2.id
from s s1 full outer join
     s s2
     on s1.color = s2.color
group by s1.id, s2.id
having sum(case when s1.color is null then 1 else 0 end) = 0 and
       sum(case when s2.color is null then 1 else 0 end) = 0

使用相同的想法,我们可以将最小s1.id指定为组的“id”。然后,该组ID为我们提供了最终聚合所需的信息:

select s3.groupid, sum(s3.quantity) as quantity, s3.color as color
from (select min(s1.id) as groupid, s2.id
      from (select s1.id, s2.id
            from s s1 full outer join
                 s s2
                 on s1.color = s2.color
            group by s1.id, s2.id
            having sum(case when s1.color is null then 1 else 0 end) = 0 and
                   sum(case when s2.color is null then 1 else 0 end) = 0
           ) ss
      group by s2.id
     ) sg join
     s s3
     on sg.id = s.id
group by sg.groupid, s3.color

在DB2中,您也可以使用listagg执行此操作。首先,您需要获取颜色列表以识别共性,然后使用它:

select min(s.id) as groupid, sum(s.quantity) as quantity, s.color
from (select id, listagg(color order by color) as thegroup
      from s
      group by id
     ) sg join
     s
     on sg.id = s.id
group by sg.thegroup, s.color

这可能比第一种解决方案更有效。