2012-12-12 63 views
0

我有兩個表與我的基表1:n的關係,我想要左連接。左連接Mulltiple表並避免重複

------------------------------- 
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 

但這正顯示出重複的表B:

1 A1 B1 C1 
1 A1 B1 C2 

我怎麼能寫這個連接忽略重複?如:

1 A1 B1  C1 
1 A1 null C2  
+0

連接正在工作,因爲它應該工作。你能解釋一下你希望你的結果看起來像什麼嗎?爲什麼你想在第二列中有NULL,當有匹配的值時? –

+0

我很喜歡我左桌上的dups,但是我希望右桌的出現能夠保持真實的關係。所以,由於'TableB'上只有一行ID'1',我只想在結果集中看到它一次。 – Paul

+0

來自tableA的值A1不能與來自tableC的值C2連接,因爲它們具有不同的ID。 –

回答

0

你要使用不同的

SELECT distinct * FROM TableA a 
LEFT JOIN TableB b 
     ON a.Id = b.Id 
LEFT JOIN TableC c 
     ON a.Id = c.Id 
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 

即一個選擇到被後面的第一行和另一把回到第二排。這有點粗糙,因爲我對你試圖閱讀的數據一無所知,但原理是正確的。你可能需要重新做一點。

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不會出現在結果中。