2012-09-04 72 views
1
SELECT cf.FK_collection, c.collectionName, 
    uf.FK_userMe, uf.FK_userYou, 
    u.userId, u.username 
FROM userFollows as uf 
INNER JOIN collectionFollows as cf ON uf.FK_userMe = cf.FK_user 
INNER JOIN collections as c ON cf.FK_collection = c.collectionId 
INNER JOIN users as u ON uf.FK_userYou = u.userId 
WHERE uf.FK_userMe = 2 

嘿傢伙。MySQL - 修復多條記錄

我試圖做這個查詢,它當然不會按我想要的那樣做,因爲它返回多行,這在某種程度上是我想要的,但事實並非如此。讓我試着解釋一下:

我試圖同時獲得collectionFollows和userFollows,以顯示用戶在網站上的活動。但是,當這樣做時,即使用戶只跟隨1,我也會有多行userFollows。這是因爲我遵循多個collectionFollow。

所以,當我告訴我的結果將返回這樣的:

John is following 'webdesign' 
John is following 'Lisa' 
John is following 'programming' 
John is following 'Lisa' 

我想知道如果我必須做出多個查詢或者使用子查詢?最佳做法是什麼?那麼我將如何編寫查詢呢?

+1

如果你知道這個問題已被問了十億次,你一定找到了至少一百萬個答案。 – GolezTrol

+0

@GolezTrol如果我有我不會寫這個問題。我也在問什麼是最好的做法,而不是其他問題。 – skolind

+0

好的。最佳做法是首先編寫一個可行的查詢(您不知道),然後您可以優化。我試圖在我的回答中解決這個問題。 – GolezTrol

回答

3

實際上,您將兩個完全無關的查詢組合在一起。我會把它們作爲單獨的查詢,特別是因爲你也這樣報告它們。如果您願意,可以使用UNION ALL來組合這些查詢。通過這種方式,無論項目的類型如何,您都只需要列出所關注項目的名稱。如果你願意,你也可以指定。

SELECT 
    cf.user, 
    cf.FK_collection as followItem, 
    c.collectionName as followName, 
    'collection' as followType 
FROM collectionFollows as cf 
INNER JOIN collections as c ON cf.FK_collection = c.collectionId 
WHERE cf.user = 2 
UNION ALL 
SELECT 
    uf.FK_userMe, 
    u.userId, 
    u.username 
    'user' as followType 
FROM userFollows as uf 
INNER JOIN users as u ON uf.FK_userYou = u.userId 
WHERE uf.FK_userMe = 2 

另一種方法是用PHP來篩選唯一值,但即使如此,你的查詢將失敗。由於內部連接,如果用戶只關注其他用戶或僅關注集合,則不會得到任何結果。您至少需要其中一個才能獲得任何結果。 您可以將INNER JOIN更改爲LEFT JOIN,但是您仍然必須後處理查詢來過濾雙打併過濾掉NULL值。

UNION ALL很快。它只是將兩個查詢結果粘貼在一起而沒有進一步處理。這與UNION不同,UNION也會過濾兩次(如DISTINCT)。在這種情況下,它不是必需的,因爲我假設用戶只能跟蹤集合或其他用戶一次,因此這些查詢將永遠不會返回重複的記錄。如果確實如此,UNION ALL會做得很好,而且會比UNION更快。

除了UNION ALL,兩個單獨的查詢也沒問題。

+0

謝謝你的回答,我會回來的。謝謝! – skolind

+0

這是完美的。非常感謝。一個非常有用的答案!我現在將閱讀有關UNION的全部內容以及它如何工作,以便我不只是複製粘貼您的答案。謝謝! – skolind

+0

'UNION ALL',而不是'UNION'。他們是不同的! :) – GolezTrol