2011-06-17 132 views
2

我有兩個表:SQL查詢是左的混合聯接和內部聯接

TableA  TableB 
id   id 
amt   amt 
idUser  idTableA 

比方說,下面的數據是在表A:

1 10 1 
2 20 1 
3 30 1 
4 40 2 
5 50 3 
6 60 4 
7 70 4 

,後面的數據是在表B中:

1 10 1 
2 20 2 
3 21 2 
4 51 5 
5 70 7 

所有字段都不能爲空。

如果我想知道在表A哪些項目有沒有「鏈接」(通過TableB.idTableA場)到tableB的,我能做到這一點查詢

SELECT a.id, a.amt 
FROM TableA a LEFT JOIN TableB b on b.idTableA = a.id 
WHERE b.idTableA IS NULL 

,它將返回以下內容:

3 30 
4 40 
6 60 
如果我想知道我可以做什麼TableA中的項目(即做有一個鏈接到tableB的)該AMT值不是每個表相同

SELECT a.id, a.amt, b.amt 
FROM TableA a INNER JOIN TableB b on b.idTableA = a.id 
WHERE a.amt <> b.amt 

,它將返回:

2 20 21 
5 50 51 

現在,我想一個查詢,執行以下操作: 回報,只有他們TableA中條目的一些有表B的鏈接idUsers(意思是對於idUser,在TableA中還必須有一些條目,兩個表之間沒有鏈接),並且鏈接的行之間至少有一個條目在這兩個表之間有不同的數量。

在我的示例中,idUser 1將由此類查詢返回,因爲TableA中的第三個條目滿足第一個條件(一些條目沒有鏈接),並且存在一個條目,其數量不同(與值關聯2 idTableA是相當於20在表A VS在表B 21)

用戶id 2將不會被返回,因爲它沒有線的兩個表之間的聯繫,

用戶id 3不會返回,因爲它不具有TableA中沒有鏈接的行B

userId 4將不會返回,因爲alth儘管TableA中有1行沒有鏈接,1行也有鏈接,但帶鏈接的行在兩個表之間的數量相同。

因此,其實這是兩個初始查詢的混合...

感謝您的輸入和我的基本格式和語言道歉,我希望這是不夠清楚:)

+0

我認爲你的查詢以'WHEREb.idTableA IS NULL'結尾,也應該返回TableA ID 4和6. – therealmitchconnors

回答

4
with loners as (
SELECT a.* 
FROM TableA a 
LEFT JOIN TableB b on b.idTableA = a.id 
WHERE b.idTableA IS NULL 
), 
diffs as (
SELECT a.* 
FROM TableA a 
INNER JOIN TableB b on b.idTableA = a.id 
WHERE a.amt <> b.amt 
) 
select loners.userID 
FROM loners 
INNER JOIN diffs on LONERS.userID = DIFFS.userID 
+0

+1比我想象的要容易...有沒有更好的(性能明智的)實現還是最好的辦法呢? – ibiza

+0

表現取決於很多。一個,你是否在尋找速度,最少的內存使用,最少的CPU使用率,最少的io使用?你在優化什麼?此外,它取決於你的底層架構是什麼,你使用了什麼索引,他們駐留的是什麼硬件,timbuctu中的天氣等等。 – therealmitchconnors

+1

但這與使用子查詢是一樣的嗎?我一直認爲,儘可能避免子查詢是好的,如果沒有子查詢,性能更好的查詢可以實現相同的結果? – ibiza

1
SELECT a.idUser 
FROM 
(SELECT a2.id, a2.amt, a2.idUser 
    FROM TableA AS a2 
    LEFT JOIN TableB AS b2 
    ON b2.idTableA = a2.id 
    WHERE b2.idTableA IS NULL 
) AS a 
INNER JOIN TableB AS b 
ON b.idTableA = a.id 
WHERE a.amt <> b.amt; 

我不確定這實際上是否更高效,但這裏是我如何做到的。

+0

感謝您的貢獻:) – ibiza