首先,我们需要确定两个“id”的“颜色”是否相同。以下查询对 进行完全外连接color
,然后按 聚合id
。如果两个id
s 具有相同的颜色,则完整的外连接始终匹配——没有 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
Using the same idea, we can assign the minimum s1.id as the "id" of the group. This group id then gives us the information needed for the final aggregation:
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
In DB2 you can also do this with listagg
. First you need to get the list of colors to identify commonality, and then use it:
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
This is probably more efficient than the first solution.