0

我希望尽可能使用 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_users. user_idtbl_usersavatar其中任何用户拥有的候选名单包含两个或多个与item_id当前所有者相同的内容。因此,假设我正在使用上述数据结构查找 user_id 1。由于 ID 的 Shortlist 与shortlist_id1 共享两个项目(即用户 1 的候选名单),我想返回user_id= 2 和avatar= 1234.jpg。

我不知道如何在纯 SQL 中做到这一点。我在想也许可以使用IN(),但我不知道这是否可行。

这是一些伪代码,希望能更好地解释我想要的内容:

为包含两个或多个 item_id 的每个候选列表选择 user_id 和头像,这些 item_id 位于 user_id = 1 拥有的候选列表中。

4

1 回答 1

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

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
于 2012-08-28T14:02:00.097 回答