-1

我有两个表与我的基表有 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    
4

3 回答 3

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

即一个选择返回第一行,另一个选择返回第二行。这有点粗糙,因为我对您尝试读取的数据一无所知,但原则是合理的。您可能需要对其进行一些修改。

于 2012-12-12T16:17:36.330 回答
0

我认为你需要做逻辑才能得到你想要的。您希望任何多个 b.id 消除它们。您可以使用识别它们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 有 2 行的 id 而 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 不会出现在结果中。

于 2012-12-12T16:26:14.970 回答
0

你想使用不同的

SELECT distinct * FROM TableA a
LEFT JOIN TableB b
       ON a.Id = b.Id
LEFT JOIN TableC c
       ON a.Id = c.Id
于 2012-12-12T16:16:07.573 回答