左连接多个表并避免重复

时间:2012-12-12 16:08:45

标签: sql oracle10g left-join

我有两个与我的基表有1:n关系的表,我想要LEFT JOIN。

-------------------------------
Table A    Table B    Table C
-------------------------------
|ID|DATA|  |ID|DATA|  |ID|DATA|
-------------------------------
 1  A1      1  B1      1  C1
 -          -          1  C2

我正在使用:

SELECT * FROM TableA a
    LEFT JOIN TableB b
           ON a.Id = b.Id
    LEFT JOIN TableC c
           ON a.Id = c.Id

但这显示了TableB的重复:

1  A1    B1   C1
1  A1    B1   C2

如何编写此连接以忽略重复项?如:

1  A1    B1     C1
1  A1    null   C2    

3 个答案:

答案 0 :(得分:0)

您想使用不同的

吗?
SELECT distinct * FROM TableA a
LEFT JOIN TableB b
       ON a.Id = b.Id
LEFT JOIN TableC c
       ON a.Id = c.Id

答案 1 :(得分:0)

将其作为UNION,即

 SELECT TableA.ID, TableB.ID, TableC.Id
   FROM TableA a
         INNER JOIN TableB b ON a.Id = b.Id
         LEFT JOIN TableC c ON a.Id = c.Id
 UNION
 SELECT TableA.ID, Null, TableC.Id
   FROM TableA a
         LEFT JOIN TableC c ON a.Id = c.Id

即。一个SELECT返回第一行,另一个返回第二行。这有点粗糙,因为我对你想要阅读的数据一无所知,但原理是合理的。您可能需要稍微重做一下。

答案 2 :(得分:0)

我认为你需要做逻辑才能得到你想要的东西。你想要任何多个b.ids来消除它们。您可以使用row_number()识别它们,然后使用case逻辑将后续值设为NULL:

select a.id, a.val,
       (case when row_number() over (partition by b.id, b.seqnum order by b.id) = 1 then val
        end) as bval
       c.val as cval
from TableA a left join
     (select b.*, row_number() over (partition by b.id order by b.id) as seqnum
      from tableB b
     ) b
     on a.id = b.id left join
     tableC c
     on a.id = c.id

我认为您不希望在B和C之间进行完全连接,因为您将获得多行。如果B对于id有2行而C有3,那么你会得到6.我怀疑你只想要3.为了达到这个目的,你想要做类似的事情:

select *
from (select b.*, row_number() over (partition by b.id order by b.id) as seqnum
      from TableB b
     ) b
     on a.id = b.id full outer join
     (select c.*, row_number() over (partition by c.id order by c.id) as seqnum
      from TableC c
     ) c
     on b.id = c.id and
        b.seqnum = c.seqnum join
     TableA a
     on a.id = b.id and a.id = c.id

这是枚举“B”和“C”列表,然后按列表中的位置加入它们。它使用完全外部联接来获取较长列表的全长。

最后一个连接引用两个表,因此TableA可以用作过滤器。 B和C中的额外ID不会出现在结果中。