2012-08-28 84 views
0

我希望儘可能使用SQL比較兩組數據。請考慮以下數據結構:比較SQL中的兩個數據集

tbl_users: 
+---------+----------+ 
| user_id | avatar | 
+---------+----------+ 
| 1 | test.jpg | 
| 2 | 1234.jpg | 
+---------+----------+ 

tbl_shortlists: 
+------+--------+ 
| id | owner | 
+------+--------+ 
| 1 | 1 | 
| 2 | 2 | 
+------+--------+ 

tbl_shortlist_items: 
+---------+--------------+ 
| item_id | shortlist_id | 
+---------+--------------+ 
| 1 |  1  | 
| 2 |  1  | 
| 3 |  1  | 
| 1 |  2  | 
| 2 |  2  | 
+---------+--------------+ 

我希望選擇tbl_usersuser_idtbl_usersavatar其中任何用戶擁有的候選名單包含與當前所有者相同的兩個或多個item_id。因此,讓我們假設我正在查找user_id 1,並使用上面的數據結構。由於具有ID的候選列表與shortlist_id 1(即用戶1的候選列表)共享兩個項目,因此我想返回user_id = 2和avatar = 1234.jpg。

我對如何在純SQL中執行此操作感到茫然。我在考慮可能會使用IN(),但我不知道這是否可行。

下面是一些僞代碼,希望能稍微解釋一下更好,我想什麼:

選擇USER_ID和含有兩個或兩個以上ITEM_IDS是在由USER_ID擁有的名單 每個名單化身 = 1.

+2

我覺得你的問題不夠清楚,你能解釋一下嗎?如果你可以使用sqlfiddle會很好 – jcho360

+0

我已經編輯了這個問題,以包含一個簡短的僞代碼,應該使事情變得更清晰。 – BenM

回答

3

與SQL一樣,它有助於將其分解成小部分。比如,你首先需要的是所有在短期列出了當前用戶擁有的項目:

SELECT Item_ID 
FROM tbl_ShortList_Items 
     INNER JOIN tbl_ShortLists 
      ON tbl_ShortLists.ID = tbl_ShortList_Items.ShortList_ID 
WHERE Owner = 1 -- CURRENT USER 

接下來,你需要誰擁有在同一個項目短名單的所有用戶,爲了說明我將建立作爲。 IN聲明,但INNER JOIN可能表現更好。

SELECT Owner 
FROM tbl_ShortList_Items 
     INNER JOIN tbl_ShortLists 
      ON tbl_ShortLists.ID = tbl_ShortList_Items.ShortList_ID 
WHERE Item_ID IN 
     -- RESULTS FROM LAST QUERY START 
     ( SELECT Item_ID 
      FROM tbl_ShortList_Items 
        INNER JOIN tbl_ShortLists 
         ON tbl_ShortLists.ID = tbl_ShortList_Items.ShortList_ID 
      WHERE Owner = 1 -- CURRENT USER 
     ) 
     -- RESULTS FROM LAST QUERY END 
AND  Owner != 1 -- CURRENT USER 

然後,您需要把這個限制於那些具有2個或更多,加入GROUP BYHAVING

SELECT Owner 
FROM tbl_ShortList_Items 
     INNER JOIN tbl_ShortLists 
      ON tbl_ShortLists.ID = tbl_ShortList_Items.ShortList_ID 
WHERE Item_ID IN 
     -- RESULTS FROM LAST QUERY START 
     ( SELECT Item_ID 
      FROM tbl_ShortList_Items 
        INNER JOIN tbl_ShortLists 
         ON tbl_ShortLists.ID = tbl_ShortList_Items.ShortList_ID 
      WHERE Owner = 1 -- CURRENT USER 
     ) 
     -- RESULTS FROM LAST QUERY END 
AND  Owner != 1 -- CURRENT USER 
GROUP BY Owner 
HAVING COUNT(DISTINCT tbl_ShortList_Items.Item_ID) > 1 

然後,您需要使用tbl_users得到化身爲這些業主

SELECT User_ID, Avatar 
FROM tbl_Users 
WHERE User_ID IN 
     -- RESULTS FROM LAST QUERY START 
     ( SELECT Owner 
      FROM tbl_ShortList_Items 
        INNER JOIN tbl_ShortLists 
         ON tbl_ShortLists.ID = tbl_ShortList_Items.ShortList_ID 
      WHERE Item_ID IN 
        ( SELECT Item_ID 
         FROM tbl_ShortList_Items 
           INNER JOIN tbl_ShortLists 
            ON tbl_ShortLists.ID = tbl_ShortList_Items.ShortList_ID 
         WHERE Owner = 1 -- CURRENT USER 
        ) 
      AND  Owner != 1 -- CURRENT USER 
      GROUP BY Owner 
      HAVING COUNT(DISTINCT tbl_ShortList_Items.Item_ID) > 1 
     ) 
     -- RESULTS FROM LAST QUERY END 

正如我所說,我認爲重新排列這個JOINs會更好地優化,但沒有測試這個理論。

SELECT User_ID, Avatar 
FROM tbl_Users 
     INNER JOIN 
     ( SELECT Owner 
      FROM tbl_ShortList_Items 
        INNER JOIN tbl_ShortLists 
         ON tbl_ShortLists.ID = tbl_ShortList_Items.ShortList_ID 
        INNER JOIN 
        ( SELECT Item_ID 
         FROM tbl_ShortList_Items 
           INNER JOIN tbl_ShortLists 
            ON tbl_ShortLists.ID = tbl_ShortList_Items.ShortList_ID 
         WHERE Owner = 1 -- CURRENT USER 
        ) CurrentUserItems 
         ON CurrentUserItems.Item_ID = tbl_ShortList_Items.Item_ID 
      WHERE Owner != 1 
      GROUP BY Owner 
      HAVING COUNT(DISTINCT tbl_ShortList_Items.Item_ID) > 1 
     ) MatchUsers 
      ON MatchUsers.Owner = tbl_Users.User_ID 
+0

感謝您的出色答案! – BenM