在同一列上完全连接同一个表而无需UNION

时间:2016-08-05 14:49:55

标签: sql postgresql

首先,问题的标题很糟糕......我希望下面的描述能够澄清情况。

问题如下;考虑一下这个表:

id    part1    part2    v
-------------------------
id1   p1       p2       v1old
id1   p3       p4       v2
id2   p1       p2       v1new
id2   p5       p6       v3

现在,我获得了id列的两个值;让我们从上面的示例数据中说出id1id2。我寻求的结果是:

part1    part2    vold    vnew
------------------------------
p1       p2       v1old   v1new
p3       p4       v2      NULL
p5       p6       NULL    v3

经过一些调查和this question的帮助后,我可以构建这个查询来解决问题:

select t1.part1, t1.part2, t1.v as vold, t2.v as vnew
    from (select part1, part2, v from t where id = 1) t1
    left join (select part1, part2, v from t where id = 2) t2
    on t1.part1 = t2.part1 and t1.part2 = t2.part2
union
select t2.part1, t2.part2, t1.v as vold, t2.v as vnew
    from (select part1, part2, v from t where id = 1) t1
    right join (select part1, part2, v from t where id = 2) t2
    on t1.part1 = t2.part1 and t1.part2 = t2.part2
;

这里的问题是重复,union将很乐意摆脱......但是有很多要删除。是否有可以避免生成重复项的版本?

2 个答案:

答案 0 :(得分:0)

我认为这就是你想要的:

select coalesce(t.part1, t2.part1) as part1,
       coalesce(t.part2, t2.part2) as part2,
       t.v as vold, t2.v as vnew
from this t full join
     this t2
     on t.part1 = t2.part1 and t.part2 = t2.part1
where (t.id = $id1 or t.id is null) and
      (t2.id = $id2 or t2.id is null)

答案 1 :(得分:0)

好的,我通过另一条路线找到了解决方案:

select t1.*, t2.value as vold, t3.value as vnew
from (select distinct part1, part2 from t where id in (1, 2)) t1
left join t t2 on t2.id = 1 and t2.part1 = t1.part1 and t2.part2 = t1.part2
left join t t3 on t3.id = 2 and t3.part1 = t1.part1 and t3.part2 = t1.part2
;