2011-04-06 92 views
1

我在這裏讀了很多加入問題,但無法理解並創建我自己的以獲得我想要的正確結果。加入在哪裏條件

我有三個表,現在是狀態成員朋友朋友表有兩列friend_id和member_id

  1. 所有三個表都member_id會員表的常見主ID
  2. 現在我想獲得所有成員和會員的朋友創建的狀態
  3. 如果我有三個成員與ID的1,2,3
  4. 朋友表有ID的1,2所以這兩個成爲朋友相互
  5. 2有5次狀態更新和1個有2個狀態和3在狀態表
  6. 1次更新,如果我對查詢部件2,它應該返回7記錄...(5 2和2爲1)和,如果我查詢針對構件1則它應該返回相同的記錄作爲點5

做我不應該返回構件3.

  • 的記錄需要改變我的表格結構?請大家幫忙如何獲得創紀錄的,我想

    three tables structure attached

  • +0

    當你說「friends table have id's 1,2」是兩行,或只有一行member_id = 1和friend_id = 2? – Skrol29 2011-04-06 10:27:16

    +0

    @ Skrol29只有一行,其中member_id = 1,friend_id = 2 – Yasir 2011-04-06 11:06:07

    回答

    1

    如何預先查詢到的朋友表,任何符合條件的成員PLUS成員本身,然後回加盟的休息方式表...

    select STRAIGHT_JOIN 
         PeopleList.Member_id, 
         members.last_name, 
         members.first_name, (etc with any other fields) 
         ms.status_id, 
         ms.description (etc with any other fields from member_status table) 
        from 
         (Select DISTINCT m.member_id 
          from Members m 
          where m.member_id = MemberDesiredVariable 
         union select f.friend_id AS member_id 
          from Friends f 
          where f.member_id = MemberDesiredVariable 
         union select f2.member_id 
          from Friends f2 
          where f2.friend_id = MemberDesiredVariable) PeopleList 
         join members 
         on PeopleList.member_id = members.member_id 
         join member_status ms 
         on PeopleList.member_id = ms.member_id 
    

    這應該讓主的人有問題,無論其在「朋友」表,任何記錄的人,如一個新的人與沒有條目但......他們至少會限定自己並加入成員和member_status表。

    然後,在您的場景中,成員1是條件,它將針對任何「Friend_IDs」的朋友進行查詢,因此DISTINCT將具有1(直接來自成員)和2,其中member_id = 1 Friend_id = 2.所以現在,這個預查詢有兩個ID並繼續獲取你想要的其他細節。

    THIRD方案是你想要成員2 ...所以,直接查詢成員表保證他們在列表中的ID進行處理,但由於他們的ID不是作爲朋友表中的「MEMBER_ID」,它有從其他人那裏查找自己的「FRIEND_ID」,並抓取該會員的ID。所以現在,會員2也會找到會員1並繼續獲取詳細信息。

    對於會員3,如果您對Friends桌面進行查詢,則根本不會收到任何記錄,即使成員3有一些狀態記錄也是如此......它必須有資格對自己進行包容用於處理...但是不會在朋友表中找到自己作爲「member_id」和「friend_id」。

    我實際上無法在我目前的位置進行測試,但邏輯上應該沒有問題。

    最後,如果你想讓朋友名稱REGARDLESS具有任何「狀態」更改,請將最後一次加入member_status更改爲LEFT JOIN。

    ---評論反饋

    我不能具體建議任何書籍,它只是來自於多年的經驗... 1.瞭解你的數據關係...
    2.找出最內層的「我想要得到什麼」。
    3.拋出所有其他元素,直到獲得標準,而不是內容。 4.保持您的主要「前提條件」......然後加入您的其他表格。 5.然後在輸出結果集中添加所需的所有其他字段

    嘗試解決複雜查詢通常可能會被所有其他人嘗試獲取的數據元素混淆。像許多其他編程任務一樣......我喜歡讓它工作,然後讓它變得漂亮。查詢也是如此。如果你的基線查詢沒有得到你想要的東西,那麼你連接在一起的多少個表格(左邊,外部或正常連接)並不重要,你的輸出將會是錯誤的。

    我還在頂部的sql中添加了「STRAIGHT_JOIN」子句。這告訴MySql按照我指示的順序執行查詢,並且沒有優化器試圖爲我思考。在加入主表(例如數百萬條記錄)以「查找」次表時,這一個子句頻繁出現,查詢引擎已錯誤地將查詢表解釋爲查詢哪些性能被殺死的主查詢表...

    嘗試在工作版本之間進行一些定時測試。如果他們具有同等的可比性,那麼我通常會選擇我能理解的情況,以防我將來需要修改/更改某些內容。

    +0

    非常感謝你DRapp它的工作原理非常好:)你沒有測試就寫出來呵呵你能否推薦任何書或者關於sql的教程,我可以提高我的sql技能...... Manji查詢也有效不知道哪一個更好,但你的查詢看起來更乾淨... – Yasir 2011-04-06 20:40:23

    +0

    沒問題,我更新了其他查詢澄清/調整的答案。 – DRapp 2011-04-07 00:25:43

    0
    -- own records 
    SELECT member_id, friend_id, user_name, description 
    FROM 
    (SELECT M.member_id, 
         M.member_id friend_id, 
         M.user_name, 
         MS.description 
        FROM members M 
        LEFT JOIN member_status MS on MS.member_id = M.member_id 
    UNION ALL 
    -- friends records 
    SELECT M.member_id, 
         F.friend_id, 
         MF.user_name, 
         MS.description 
        FROM members M 
        JOIN (  SELECT friend_id member_id, member_id friend_id from friends 
         UNION SELECT member_id, friend_id from friends) F 
               ON F.member_id = M.member_id 
        LEFT JOIN member_status MS on MS.member_id = F.friend_id 
        LEFT JOIN members MF  on MF.member_id = F.friend_id) R 
    WHERE R.member_id = 1 
    
    +0

    Manji非常感謝您的支持,只需添加或語句很少....加入friends.member_id = members.member_id或friends.friend_id = members。 member_id ...你能描述整個查詢嗎?詳細信息:) – Yasir 2011-04-06 11:16:02

    +1

    如果成員沒有朋友,那麼即使成員具有狀態,此查詢也不會返回任何記錄。 – Skrol29 2011-04-06 11:35:29

    +0

    嗨Manji ....有1個問題查詢返回成員id 1,2相同的第一和第二名稱,但返回成員1和2的記錄它沒關係在哪裏作出改變,所以它返回不同的第一,第二個名稱? – Yasir 2011-04-06 11:42:41

    0

    這裏是使用UNION子句的解決方案。如果每個SELECT的結果都很短(假設少於1000行),那麼它比使用OR的LEFT JOIN更快。

    如果「對方的朋友」你的意思是你想要的:
       (一)成員的狀態標記爲朋友
        +
       (b)該成員的地位其中認爲的成員標記爲朋友
    那麼你應該使用下面的樹UNION。
    如果你只想要(a),然後刪除最後一個UNION。

    SELECT s.status_id 
    FROM member_status AS s 
    WHERE ([email protected]) 
    
    UNION ALL 
    
    SELECT s.status_id 
    FROM member_status AS s 
    INNER JOIN friends AS f ON (s.member_id=f.friend_id) 
    WHERE ([email protected]) 
    
    UNION ALL 
    
    SELECT s.status_id 
    FROM member_status AS s 
    INNER JOIN friends AS f ON (s.member_id=f.member_id) 
    WHERE ([email protected])