17

The question you're asking appears subjective and is likely to be closed.

タイトル欄に記入しているときに、上記の恐ろしい警告を見ても驚かなかった。

私はほとんどすべてのスレッドについて読んでいますが、自分がやりたい正しい解決策を見つけたかどうかはわかりませんfriends of friendsmutual friends

英語もSQLも苦手でごめんなさい。

両方の言語が苦手なのに、どうすれば正しい答えを見つけることができますか?

私は尋ねなければならないと決めました。down-vote私はsまたは任意のsのために自分自身を失望させませんduplication warning

答えが欲しいので、さらに同様の問題が解決される可能性があるため、可能な限り誠実に書き留めておきます。

友達関係のテーブルがあります。

FRIEND (TABLE)
-----------------------------------
PLAYER_ID(PK,FK)   FRIEND_ID(PK,FK)
-----------------------------------
1                  2                 // 1 knows 2
2                  1                 // 2 knows 1
1                  3                 // 1 knows 3
2                  3                 // 2 knows 3
2                  4                 // 2 knows 4
2                  5                 // 2 knows 5 // updated
3                  5                 // 3 knows 5 // updated
1                  100
1                  200
1                  300
100                400
200                400
300                400

どちらもテーブルcomposite primary keysからの外部キーです。PLAYER

そんな素敵な人たちに「人はお互いを知っている」と聞いて答えてもらいました。

テーブルからの知人のためのSQLビュー

そして、私はこのような見方をしています。

ACQUAINTANCE (VIEW)
-----------------------------------
PLAYER_ID(PK,FK)   FRIEND_ID(PK,FK)
-----------------------------------
1                  2                 // 1 knows 2
2                  1                 // 2 knows 1

お気づきかもしれませんが、この関係のビジネスロジックには次の2つの目的があります。

  1. 1人のプレーヤーは、自分が他の誰かを知っていると言うことができます。
  2. 両方の人がお互いを知っていると言うとき、彼らは知人と言うことができます。

そして今、私は知りたいのですが

  1. 他のPLAYER_IDの選択
  2. 与えられたPLAYER(PLAYER_ID)で(たとえば1)
  3. それぞれが「与えられたPLAYERの直接の友達の友達」の1人です
  4. それぞれがPLAYER自身ではないもの(1-> 2-> 1を除く)
  5. それぞれがPLAYERの直接の友達ではありません(1-> 2-> 3-by 1-> 3から3を除く)
  6. 可能であれば、相互の友達の数で注文してください。

「あなたが知っているかもしれない人々」のSQLクエリでのJustinNiessnerの答えは、私がたどらなければならない最も近いパスだと思います。

前もって感謝します。

この件名が本当に重複していて必要ない場合は、スレッドを閉じます。

アップデート - - - - - - - - - - - - - - - - - - - - - - - - - -------------

RaphaëlAlthausのコメントwhose name is same with my future daughter(それは男の子の名前ですか?)、

friends of friends of 13は理由の候補です

1 knows 2
2 knows 3

しかし除外されたのは

1 already knows 3

given player基本的に私はのために奉仕したい

people he or she may know
which is not himself or herself // this is nothing but obvious
which each is not already known to himself

上記の表で

by 1 -> 2 -> 4 and 1 -> 3 -> 5

4 and 5 can be suggested for 1 as 'people you may know'

order by number of mutual friends will be perfect
but I don't think I can understand even if someone show me how. sorry.

ありがとうございました。

アップデート - - - - - - - - - - - - - - - - - - - - - - - - - --------------------

FROM HERE WITH VARIOUS PEOPLE正解でなくても、学んだことから一歩ずつやってみないといけないと思います。何か問題があれば教えてください。

まず、FRIENDテーブル自体に自分で参加させてください。

SELECT *
FROM FRIEND F1 INNER JOIN FRIEND F2 ON F1.FRIEND_ID = F2.PLAYER_ID

プリント

+-----------+-----------+-----------+-----------+
| PLAYER_ID | FRIEND_ID | PLAYER_ID | FRIEND_ID |
+-----------+-----------+-----------+-----------+
|         1 |         2 |         2 |         1 |
|         1 |         2 |         2 |         3 |
|         1 |         2 |         2 |         4 |
|         1 |         2 |         2 |         5 |
|         1 |         3 |         3 |         5 |
|         2 |         1 |         1 |         2 |
|         2 |         1 |         1 |         3 |
|         2 |         3 |         3 |         5 |
+-----------+-----------+-----------+-----------+

F2.FRIEND_IDのみ

SELECT F2.FRIEND_ID
FROM FRIEND F1 INNER JOIN FRIEND F2 ON F1.FRIEND_ID = F2.PLAYER_ID

プリント

+-----------+
| FRIEND_ID |
+-----------+
|         1 |
|         3 |
|         4 |
|         5 |
|         5 |
|         2 |
|         3 |
|         5 |
+-----------+

1つだけ

SELECT F2.FRIEND_ID
FROM FRIEND F1 INNER JOIN FRIEND F2 ON F1.FRIEND_ID = F2.PLAYER_ID
WHERE F1.PLAYER_ID = 1;

プリント

+-----------+
| FRIEND_ID |
+-----------+
|         1 |
|         3 |
|         4 |
|         5 |
|         5 |
+-----------+

1ではありません

SELECT F2.FRIEND_ID
FROM FRIEND F1 INNER JOIN FRIEND F2 ON F1.FRIEND_ID = F2.PLAYER_ID
WHERE F1.PLAYER_ID = 1 
AND F2.FRIEND_ID != 1;

プリント

+-----------+
| FRIEND_ID |
+-----------+
|         3 |
|         4 |
|         5 |
|         5 |
+-----------+

1の直接の知識ではありません

SELECT F2.FRIEND_ID
FROM FRIEND F1 INNER JOIN FRIEND F2 ON F1.FRIEND_ID = F2.PLAYER_ID
WHERE F1.PLAYER_ID = 1
AND F2.FRIEND_ID != 1
AND F2.FRIEND_ID NOT IN (SELECT FRIEND_ID FROM FRIEND WHERE PLAYER_ID = 1);

プリント

+-----------+
| FRIEND_ID |
+-----------+
|         4 |
|         5 |
|         5 |
+-----------+

私はそこに着いていると思います。

アップデート - - - - - - - - - - - - - - - - - - - - - - - - - --------------------------------

次のパスが追加されました

1 -> 100 -> 400
1 -> 200 -> 400
1 -> 300 -> 400

そして最後のクエリは(再び)出力します

+-----------+
| FRIEND_ID |
+-----------+
|         4 |
|         5 |
|         5 |
|       400 |
|       400 |
|       400 |
+-----------+

ついに候補者を獲得しました:4、5、400

確実distinctに仕事をすることを第一の目標に

SELECT DISTINCT F2.FRIEND_ID
FROM FRIEND F1 INNER JOIN FRIEND F2 ON F1.FRIEND_ID = F2.PLAYER_ID
WHERE F1.PLAYER_ID = 1
AND F2.FRIEND_ID != 1
AND F2.FRIEND_ID NOT IN (SELECT FRIEND_ID FROM FRIEND WHERE PLAYER_ID = 1);

プリント

+-----------+
| FRIEND_ID |
+-----------+
|         4 |
|         5 |
|       400 |
+-----------+

そして今、相互カウントによる注文が必要です。

各候補者の相互の友達の数は次のとおりです。

+-----------+
| FRIEND_ID |
+-----------+
|         4 | 1 (1 -> 2 -> 4)
|         5 | 2 (1 -> 2 -> 5, 1 -> 3 -> 5)
|       400 | 3 (1 -> 100 -> 400, 1 -> 200 -> 400, 1 -> 300 -> 400)
+-----------+

相互の友達の数で計算して注文するにはどうすればよいですか?

SELECT F2.FRIEND_ID, COUNT(*)
FROM FRIEND F1 INNER JOIN FRIEND F2 ON F1.FRIEND_ID = F2.PLAYER_ID
WHERE F1.PLAYER_ID = 1
AND F2.FRIEND_ID != 1
AND F2.FRIEND_ID NOT IN (SELECT FRIEND_ID FROM FRIEND WHERE PLAYER_ID = 1)
GROUP BY F2.FRIEND_ID;

プリント

+-----------+----------+
| FRIEND_ID | COUNT(*) |
+-----------+----------+
|         4 |        1 |
|         5 |        2 |
|       400 |        3 |
+-----------+----------+

わかった!

SELECT F2.FRIEND_ID, COUNT(*) AS MFC
FROM FRIEND F1 INNER JOIN FRIEND F2 ON F1.FRIEND_ID = F2.PLAYER_ID
WHERE F1.PLAYER_ID = 1
AND F2.FRIEND_ID != 1
AND F2.FRIEND_ID NOT IN (SELECT FRIEND_ID FROM FRIEND WHERE PLAYER_ID = 1)
GROUP BY F2.FRIEND_ID
ORDER BY MFC DESC;

プリント

+-----------+-----+
| FRIEND_ID | MFC |
+-----------+-----+
|       400 |   3 |
|         5 |   2 |
|         4 |   1 |
+-----------+-----+

誰かがこれを確認できますか?そのクエリは最適ですか?ビューとして作成するときにパフォーマンスの問題が発生する可能性はありますか?

ありがとうございました。

アップデート - - - - - - - - - - - - - - - - - - - - - - - - - -------------------------------------------

私は次のようにビューを作成しました

CREATE VIEW FOLLOWABLE AS
    SELECT F1.PlAYER_ID, F2.FRIEND_ID AS FOLLOWABLE_ID, COUNT(*) AS MFC
    FROM FRIEND F1 INNER JOIN FRIEND F2 ON F1.FRIEND_ID = F2.PLAYER_ID
    WHERE F2.FRIEND_ID != F1.PLAYER_ID
    AND F2.FRIEND_ID NOT IN (SELECT FRIEND_ID FROM FRIEND WHERE PLAYER_ID = F1.PLAYER_ID)
    GROUP BY F2.FRIEND_ID
    ORDER BY MFC DESC;

とテストされました。

mysql> select * from FOLLOWABLE;
+-----------+---------------+-----+
| PlAYER_ID | FOLLOWABLE_ID | MFC |
+-----------+---------------+-----+
|         1 |           400 |   3 |
|         1 |             5 |   2 |
|         2 |           100 |   1 |
|         2 |           200 |   1 |
|         2 |           300 |   1 |
|         1 |             4 |   1 |
+-----------+---------------+-----+
6 rows in set (0.01 sec)

mysql> select * from FOLLOWABLE WHERE PLAYER_ID = 1;
+-----------+---------------+-----+
| PlAYER_ID | FOLLOWABLE_ID | MFC |
+-----------+---------------+-----+
|         1 |           400 |   3 |
|         1 |             5 |   2 |
|         1 |             4 |   1 |
+-----------+---------------+-----+
3 rows in set (0.00 sec)
4

1 に答える 1

8

この 編集を使用する

SELECT `friend_id` AS `possible_friend_id`
FROM `friends`
WHERE `player_id` IN (        --selecting those who are known
    SELECT `friend_id`        --by freinds of #1
    FROM `friends`
    WHERE `player_id` = 1) 
AND `friend_id` NOT IN (      --but not those who are known by #1
    SELECT `friend_id`
    FROM `friends`
    WHERE `player_id` = 1)
AND NOT `friend_id` = 1       --and are not #1 himself
                              --if one is known by multiple people
                              --he'll be multiple time in the list
GROUP BY `possible_friend_id` --so we group
ORDER BY COUNT(*) DESC        --and order by amount of repeatings
于 2012-06-11T13:35:59.113 に答える