2014-10-05 130 views
1

我有兩個表,followfollowed。我想獲得follow表中的所有行,例如follow.screen != followed.following_screen_name兩個表之間的MySQL表比較

後續表

ID screen_name 
----------------- 
1  eddie 
2  jason 
3  omar 
4  jonathan 
5  jack 

其次表

ID my_screen_name following_screen_name 
------------------------------------------- 
1  john    eddie 
2  kenny    eddie 
3  kenny    omar 
4  john    jason 
5  john    omar 

查詢我試過,沒有工作

SELECT follow.screen_name from follow, followed where followed.my_screen_name='john' 
AND follow.screen_name != followed.following_screen_name 

預期結果

ID screen_name 
----------------- 
1  jonathan  
2  jack  

回答

3

,你可以通過做一個LEFT JOIN

SELECT F.screen_name FROM follow F 
LEFT JOIN followed FD 
on F.screen_name = FD.my_screen_name 
OR F.screen_name = FD.following_screen_name 
WHERE FD.my_screen_name IS NULL 
and FD.following_screen_name IS NULL 

另一種方式得到這個是用NOT EXISTS,獲取存在於隨後的所有行,做NOT EXISTS子句,以獲得預期的結果。

SELECT F.screen_name FROM follow F 
WHERE NOT EXISTS 
(
    SELECT 1 FROM followed FD 
    WHERE F.screen_name = FD.my_screen_name 
    OR F.screen_name = FD.following_screen_name 
) 
+0

+1。 「外連接」查詢的WHERE子句中的謂詞使其成爲「反連接」模式......來自'F'的所有行以及來自'D'的匹配行,然後排除所有具有匹配的行。 (Kudos指出有多種模式返回指定的結果集。) – spencer7593 2014-10-05 22:55:15

+0

@JohnDoe,你需要用John替換F.screen_name作爲第一個條件,並用AND替換OR。這裏是sql小提琴。 http://www.sqlfiddle.com/#!2/7ef0a/5 – radar 2014-10-06 00:02:20

+0

謝謝你,我愛你兄弟! – 2014-10-06 00:02:42

0

有很多方法可以解決這個問題,而是適用於所有的是,你需要將follow.screen_name比較兩者followed.my_screen_name和followed.following_screen__name。

一種方法是用UNION不使用:

select screen_name 
from follow 
where screen_name not in (
    select following_screen_name 
    from followed 
    where following_screen_name is not null 
    union all 
    select my_screen_name 
    from followed 
    where my_screen_name is not null 
) 

雖然這種做法是爲了清晰不錯,如使用左加入或不存在,它可能不是性能良好。

+0

我們需要小心子查詢不返回任何NULL值。 (我們可以保證列不是NULL,但缺少保證,在更一般的情況下,我們需要在子查詢中添加'col IS NOT NULL'謂詞。) – spencer7593 2014-10-05 22:57:50

+0

@ spencer7593確實。 – jpw 2014-10-05 23:02:54

0

提取mysql語法和邏輯的好地方是here。 但試試這個代碼,它選擇的每一行,其中SCREEN_NAME不相同,在接下來的兩個查詢產生的任何東西:

SELECT * from follow WHERE screen_name 
not in (select screen_name from followed) 
AND not in (select followed_screen_name from followed); 

最後兩個查詢看起來這和WHERE過濾所有行出與屏幕名稱與下面的字段相同。

my_screen_name following_screen_name 
------------------------------------- 
john    eddie 
kenny    eddie 
kenny    omar 
john    jason 
john    omar 
+0

這是一個簡單的解決方法,謝謝! – apoorvk 2014-10-05 23:08:58

+0

請注意,如果任一子查詢返回NULL值,則外部查詢將返回零行。 (表達式'col NOT IN('a',NULL,...)'永遠不會返回TRUE,因爲這相當於col <> NULL AND col <>'a'...'。 – spencer7593 2014-10-06 02:46:16