2017-02-01 28 views
0

如何處理您想要使用Left Join的情況,因爲數據可能存在也可能不存在。但是,如果Left Join確實找到了一些數據,那麼您想通過將另一個表上的左連接數據加入來進一步限制這些左連接數據? (不從結果中刪除原始數據)。左加入進一步的條件/加入

我認爲它可能需要進一步JoinWhere或子查詢。

這裏是我的嘗試:

SELECT users.*, failed_logins.* 
FROM users 
LEFT JOIN failed_logins ON failed_logins.user_id = users.user_id 
INNER JOIN banned ON banned.ip_address = failed_logins.ip_address 

但是這會導致如果在banned沒有數據匹配failed_logins應顯示的數據。

如果在banned中存在匹配的行,我們希望包含來自bannedfailed_logins的行。否則應排除failed_loginsbanned的行。但應始終包含從users獲取的數據。

+1

你的問題不是很清楚,我..請更新您的查詢,並添加適當的數據樣本和預期的結果 – scaisEdge

+0

爲什麼user.user_id應等於emails.email_id?也許你可以添加表結構,使我們可以幫助您 –

+0

感謝您的意見,更新的問題是,我可以清楚。之後會添加例如數據如果需要的話,但不得不把頭伸出現在。 – Andrew

回答

2

INNER JOIN中的條件將要求failed_logins.ip_address具有非NULL值。任何具有該列的NULL值的行都將被排除。這將消除連接的「外部」failed_logins。 (在users任何行不具有匹配的行failed_logins,外聯接將從failed_logins創造一個虛擬的匹配行,所有匹配的虛擬行中的列將是NULL。

所以,我們需要要返回的方式允許failed_logins.ip_addressNULL值。

一種選擇是,以使該內連接外連接。也就是說,LEFT取代INNER

還有一些其他的方式來處理這種類型的的問題,但這實際上取決於我們想返回的結果集d預期的結果將對澄清規範有很長的路要走。


編輯

重新閱讀的問題後,它仍然是不明確的,我們希望返回的結果。爲什麼我們需要查看banned表? 「如果數據確實存在,過濾數據」並不能真正解釋規範。

如果在banned中有匹配的行,我們想要排除結果集中的行嗎?或者,我們想要返回banned中不存在匹配行的行。


隨訪

不要的failed_loginsbanned第一之間加入,在共線視圖(或,派生表使用MySQL說法)。然後在users和派生表之間進行外連接。

作爲一個例子:

SELECT users.* 
    , fl.* 
    FROM users 
    LEFT 
    JOIN (SELECT f.user_id 
       , f.ip_address 
      FROM failed_logins f 
      JOIN banned b 
      ON b.ip_address = f.ip_address 
     ) fl 
    ON fl.user_id = users.user_id 
ORDER BY users.user_id, fl.ip_address 

鑑於failed_logins樣本數據:

user_id  ip_address 
---------- ------------ 
    111  127.0.0.1 
    111  192.168.0.1 
    222  127.0.0.1 
    333  192.168.0.1 
    444  4.4.4.4 

banned樣本數據

ip_address 
---------- 
127.0.0.1 

並假設users包含五個行,111通555,該查詢應該返回:

user_id user_id ip_address 
------- ------- ---------- 
111  111  127.0.0.1 
222  222  127.0.0.1 
333  (null) (null) 
444  (null) (null) 
555  (null) (null) 

如果這不符合規格,請考慮提供一些示例數據(包括應該和不應該被返回的行例的例子),與預期輸出一起。

+0

感謝您的努力,更新的問題是,我可以清楚。之後會添加例如數據如果需要的話,但不得不把頭伸出現在。 – Andrew