0

ここに画像の説明を入力

こんにちは、ユーザーとフレンドの 2 つのテーブルがあります (friend_status = 1 はリクエストが送信されたことを意味し、friend_status = 2 は彼らがフレンドであることを意味します)。今、すべてのユーザーが特定のユーザーの友達ではないことを選択したいと思います。実行する方法?

現在のユーザーが1であると仮定します。このSQLを試しました。動作しますが、長すぎて遅いです。1 つ目は、user1 に要求を送信したが受け入れられなかったすべてのユーザーを選択します。2 番目は、すべてのユーザーが user1 から要求を受信することを選択します。3 番目と 4 番目は、「友達」テーブルにないすべてのユーザーを選択します。

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

更新:写真を追加します。 ここに画像の説明を入力

4

4 に答える 4

2
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

あなたは以前ここで質問をしまし- 「誰とも友達ではないユーザーを選択してください」LEFT JOIN.

それに基づいて、特定のユーザーと友達ではないユーザーを選択するには、その特定のユーザーの ID をLEFT JOIN条件 ( )に追加するだけです1 IN (b.sender, b.receiver

マイナーな編集:ユーザーが自分自身を友達にできない限り、選択対象のユーザーを選択しても意味がありません!! だから私は追加しましWHERE a.user_id <> 1た。

于 2012-06-25T07:41:38.240 に答える
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)

ここで、送信者 = 1 は、ユーザー ID = 1 を意味します。ユーザー ID を渡して、この条件を制限できます。また、ステータス 0 は、彼がフレンドではないことを意味します。および 1 、 2 、 3 はあなたのルールに従っています

于 2012-06-25T07:40:57.390 に答える
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 を 2 番目のパラメーターの値で置き換えます。この場合、friends テーブルに一致するフレンドが存在しない場合、friend_status は 0 として扱われることを意味します。これにより、UNION の選択数を半分に減らすことができます。

于 2012-06-25T07:13:42.293 に答える
1

user_id1に対してクエリを実行するとします。

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 のユーザーは、最後の行を使用してクエリから除外されます。自分と友達になれなくても、最終的なクエリ結果には表示されないはずだからです。

于 2012-06-25T07:15:59.080 に答える