比较SQL中的两个数据集

时间:2012-08-28 13:41:03

标签: mysql 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共享两个shortlist_id 1项(即用户1的候选名单),我想返回user_id = 2和avatar = 1234.jpg。

我不知道如何在纯SQL中执行此操作。我当时认为可以使用IN(),但我不知道这是否有效。

这里有一些伪代码,希望能更好地解释一下我想要的东西:

选择user_id和头像 对于每个候选名单,其中包含两个或多个列表中的item_id 由user_id = 1拥有。

1 个答案:

答案 0 :(得分: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

然后,您需要通过添加GROUP BYHAVING

将此限制为具有2个或更多的广告。
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

正如我所说,我认为将其重新安排到JOIN将会更好地进行优化,但尚未对此理论进行测试。

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