所以我有这个问题:
SELECT DISTINCT(b.friend_id) AS possible_id
FROM friend_friends a
JOIN friends_friends b
ON b.user_id = a.friend_id
WHERE a.user_id = 1703122278
它会检索特定用户的朋友的朋友。
我有另一个数据库,其中包含那些说他们不是朋友的人的数据。
以下是获取所述非朋友列表的查询:
SELECT friend_id
FROM friends_not_friends
WHERE user_id = 1703122278
AND not_friends = 1
然后我从可能的朋友列表中比较不是朋友的列表,并从列表中删除不是朋友。
如何在不使用子查询的情况下组合这两个查询,而是使用连接?
答案 0 :(得分:3)
SELECT DISTINCT(b.friend_id) AS possible_id
FROM friend_friends a
JOIN friends_friends b
ON b.user_id = a.friend_id
LEFT JOIN friends_not_friends n
ON b.friend_id = n.friend_id
AND n.user_id = a.user_id
AND n.not_friends = 1
WHERE a.user_id = 1703122278
AND n.friend_id IS NULL
这显示了
(1st list of friends of friends of 1703122278)
MINUS
(2nd list of not friends of 1703122278)
我希望你不要
list of friends of
(friends of 1703122278
minus
(2nd list of not friends of 1703122278)
)
简单地说,这是使用NOT IN
的查询。
我个人觉得这些更清楚,但速度可能不太有效。
-- Friends of friends of a user
SELECT DISTINCT(b.friend_id) AS possible_id
FROM friend_friends b -- the b and a aliases
WHERE b.user_id IN -- can be removed
( SELECT a.friend_id
FROM friends_friends a
WHERE a.user_id = 1703122278
)
;
和被问到的人:
-- Friends of friends of a user that
-- are also not not_friends of the user:
SELECT DISTINCT(b.friend_id) AS possible_id
FROM friend_friends b -- the b, a and n aliases
WHERE b.user_id IN -- can be removed too
( SELECT a.friend_id
FROM friends_friends a
WHERE a.user_id = 1703122278
)
AND b.friend_id NOT IN
( SELECT n.friend_id
FROM friends_not_friends n
WHERE n.user_id = 1703122278
AND n.not_friends = 1
)
;
答案 1 :(得分:1)
我认为mysql中有一个相关函数 - 可能是左连接或NOT IN子句
答案 2 :(得分:1)
这是一个过滤两个级别上的“不是朋友”的解决方案(它过滤了用户的非朋友和非朋友的朋友用户):
SELECT
DISTINCT(b.friend_id) AS possible_id
FROM
friend_friends a
JOIN friend_friends b ON b.user_id = a.friend_id
LEFT JOIN friends_not_friends nfa
ON a.friend_id = nfa.user_id and nfa.not_friends = 1
LEFT JOIN friends_not_friends nfb
ON b.friend_id = nfb.user_id and nfb.not_friends = 1
WHERE
a.user_id = 1703122278
AND nfa.friend_id IS NULL
AND nfb.friend_id IS NULL
“技巧”是执行LEFT JOIN
并检查是否没有数据(NULL
)。
顺便说一句 - 是否有理由不想进行次选?有时LEFT JOIN
- 方式更快,但子选择通常是一个不错的选择。
答案 3 :(得分:0)
尝试左外连接到friend_not_friends
表(在friend_id上匹配,过滤user_id和not_friends标志),然后消除not_friends
中匹配行的行(即消除not_friend id为NOT NULL的行
SELECT DISTINCT(f.friend_id) AS possible_id
FROM friend_friends a
JOIN friends_friends f
ON f.user_id = a.friend_id
LEFT
JOIN friends_not_friends n
ON n.user_id = a.user_id
AND n.friend_id = f.friend_id
AND n.not_friends = 1
WHERE a.user_id = 1703122278
AND n.user_id IS NULL
诀窍是过滤掉匹配的行,在friends_not_friends
表中留下未找到匹配的行。它是查询中的最后一个谓词(n.user_id IS NULL),为您进行过滤。
如果没有使用子查询的要求,那么这样的东西也会起作用:
SELECT DISTINCT(f.friend_id) AS possible_id
FROM friend_friends a
JOIN friends_friends f
ON f.user_id = a.friend_id
WHERE a.user_id = 1703122278
AND NOT EXISTS
( SELECT 1
FROM friends_not_friends n
WHERE n.friend_id = f.friend_id
AND n.user_id = a.user_id
AND n.not_friends = 1
)