选择用户不是特定用户的朋友

时间:2012-06-25 06:55:16

标签: mysql sql

enter image description here

嗨,我有这两个表:用户和朋友(friend_status = 1表示请求已发送,friend_status = 2表示他们是朋友)。现在我想选择所有用户都不是特定用户的朋友。怎么办?

假设当前用户是1.我尝试了这个SQL。它有效,但它太长而且很慢。第一个选择所有用户向user1发送请求但不被接受。第二个选择所有用户从user1接收请求。第三个和第四个选择所有用户不在“朋友”表中。

SELECT user_id, name, email
                FROM
                (
                    SELECT user_id, name, email
                    FROM users u INNER JOIN friends f ON u.user_id = f.sender
                    WHERE f.receiver = 1 AND friend_status <> 2
                    UNION
                    SELECT user_id, name, email
                    FROM users u INNER JOIN friends f ON u.user_id = f.receiver
                    WHERE f.sender = 1 AND friend_status <> 2
            UNION
            SELECT u.user_id, u.name, u.email
                    FROM users u LEFT JOIN friends f ON u.user_id = f.sender
                    WHERE f.receiver IS NULL
                    GROUP BY user_id
                UNION 
            SELECT u.user_id, u.name, u.email
                    FROM users u LEFT JOIN friends f ON u.user_id = f.receiver
                    WHERE f.sender IS NULL
                    GROUP BY user_id
                ) T
        GROUP BY user_id

更新:添加图片。 enter image description here

4 个答案:

答案 0 :(得分:1)

您可以通过使用以下内容来简化此操作:

SELECT user_id, name, email
FROM
(
    SELECT u.user_id, u.name, u.email
    FROM users u LEFT JOIN friends f ON u.user_id = f.sender
    WHERE IFNULL(friend_status,0) <> 2
    GROUP BY user_id
    UNION
    SELECT u.user_id, u.name, u.email
    FROM users u LEFT JOIN friends f ON u.user_id = f.receiver
    WHERE IFNULL(friend_status,0) <> 2
    GROUP BY user_id
) T
GROUP BY user_id

IFNULL函数返回第一个参数的值,用值第二个参数的值替换NULL。在这种情况下,如果friends表中没有匹配的朋友,则表示friend_status将被视为0,这允许您将UNION中的选择数减少一半。

答案 1 :(得分:1)

假设您要在user_id 1:

上执行查询
SELECT user_id, name, email
FROM users AS u
WHERE NOT EXISTS (SELECT * FROM friends AS f
                  WHERE (f.sender = u.user_id AND f.receiver = 1 AND f.friend_status = 2)
                  OR (f.sender = 1 AND f.receiver = u.user_id AND f.friend_status = 2)
                 )
AND u.user_id <> 1

子查询获取所有已建立的友谊关系,其中用户1是发送者或接收者。外部查询选择不存在此类关系的所有用户。 ID为1的用户使用最后一行从查询中排除,因为即使他不能与自己成为朋友,我想他不应该出现在最终的查询结果中。

答案 2 :(得分:1)

尝试此查询

select
  u.user_id,
  u.name,
  u.email,
  ifnull(f.friend_status,0) as Relation
from users as u
  left join friends as f
    on f.sender = u.user_id
where u.user_id not in(select
             sender
               from friends
               where sender = 1)

此处sender = 1表示用户id = 1.您可以传递用户ID以限制此条件。状态0也表示他不是朋友。和1,2,3是根据你的规则

答案 3 :(得分:1)

SELECT
    a.user_id,
    a.name,
    a.email,
    b.status IS NOT NULL AS friend_status
FROM
    users a
LEFT JOIN
    friends b ON 
        a.user_id IN (b.sender, b.receiver) AND
        1 IN (b.sender, b.receiver)
WHERE
    (b.friend_id IS NULL OR b.status <> 2) AND
    a.user_id <> 1

您之前曾问过here - “选择不与任何人成为朋友的用户”,我提供的answer使用了LEFT JOIN

在此基础上,为了选择不是 特定 用户的朋友,我们只需要将该特定用户的ID添加到{{1 condition(LEFT JOIN)。

次要编辑:除非用户可以与他/她自己交朋友,否则选择我们选择的用户也没有意义!!所以我添加了1 IN (b.sender, b.receiver