我希望尽可能使用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_id
和tbl_users
。avatar
,其中任何用户拥有的候选名单包含两个或更多相同的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拥有。
答案 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 BY
和HAVING
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