SQL-Auswahl von Personen, die Sie vielleicht kennen

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

Ich war nicht überrascht, als ich oben sahschreckliche Warnung während ich das Titelfeld ausfüllte.

Ich habe fast jeden Thread gelesen, über den ich gesprochen habefriends of friends odermutual friends aber ich bin nicht sicher, ob ich die richtige Lösung gefunden habe, die ich tun möchte.

Es tut mir leid, dass ich weder Englisch noch SQL kann.

Wie finde ich die richtige Antwort, obwohl ich in beiden Sprachen nicht gut bin?

Ich entschied, dass ich fragen muss. Ich werde mich nicht enttäuschendown-votes oder irgendwelcheduplication warnings.

Da ich die Antwort haben möchte, werde ich mich so herzlich wie möglich für alle weiteren ähnlichen Probleme aufschreiben, denen geholfen werden kann.

Ich habe einen Tisch für Freundschaften.

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

Beidecomposite primary keys sind auch Fremdschlüssel ausPLAYER Tabelle.

Ich fragte und wurde von so netten Leuten für "Leute kennen sich" beantwortet.

SQL-Ansicht zur Bekanntschaft aus der Tabelle.

Und ich habe eine Ansicht wie diese.

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

Wie Sie vielleicht bemerkt haben, verfolgt die Geschäftslogik dieser Beziehung zwei Zwecke.

Ein Spieler kann sagen, dass er oder sie jemanden kennt.Wenn beide Leute sagen, dass sie sich kennen, können sie als Bekannte bezeichnet werden.

Und jetzt möchte ich wissen, ob es einen guten Weg dafür gibt

Auswahl anderer PLAYER_IDsMit gegebenem PLAYER (PLAYER_ID) (sprich 1)Welches ist jeweils einer von "Freunden der direkten Freunde von PLAYER"?Welches jeder nicht der SPIELER selbst ist (außer 1 -> 2 -> 1)Welche sind nicht die direkten Freunde des SPIELERS (ausgenommen 3 von 1 -> 2 -> 3 von 1 -> 3)Wenn möglich, nach Anzahl der gemeinsamen Freunde bestellen.

Ich denke, die Antwort von Justin Niessner ist richtigSQL-Abfrage "Personen, die Sie vielleicht kennen" ist der nächste Weg, dem ich folgen muss.

Danke im Voraus.

Ich werde den Thread schließen, wenn dieses Thema wirklich dupliziert und nicht notwendig ist.

UPDATE ------------------------------------------------- -------------

für den Kommentar von Raphaël Althauswhose name is same with my future daughter (Ist es der Name des Jungen?),

3 ist ein Kandidat fürfriends of friends of 1 da

1 knows 2
2 knows 3

aber ausgeschlossen da

1 already knows 3

Grundsätzlich möchte ich für die dienengiven player das

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

Mit obiger Tabelle

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.

Vielen Dank.

UPDATE ------------------------------------------------- --------------------

Ich denke, ich muss Schritt für Schritt selbst versuchen, was ich gelernt habeFROM HERE WITH VARIOUS PEOPLE Auch wenn es nicht die richtige Antwort ist. Bitte lassen Sie mich wissen, wenn ich etwas falsch mache.

Lassen Sie mich zunächst selbst am FRIEND-Tisch teilnehmen.

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

druckt

+-----------+-----------+-----------+-----------+
| 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 |
+-----------+-----------+-----------+-----------+

Nur F2.FRIEND_ID

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

druckt

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

nur für 1

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

druckt

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

nicht 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;

druckt

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

keine direkten Bekannten von 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);

druckt

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

Ich glaube, ich komme dorthin.

UPDATE ------------------------------------------------- ----------------

Folgende Pfade hinzugefügt

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

Und die letzte Abfrage wird (erneut) gedruckt

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

Endlich habe ich die Kandidaten: 4, 5, 400

Puttendistinct Arbeite mit Sicherheit für das primäre Ziel

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);

druckt

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

Und jetzt ist eine Bestellung in gegenseitiger Absprache erforderlich.

Hier kommt die Anzahl der gemeinsamen Freunde für jeden Kandidaten.

+-----------+
| 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)
+-----------+

Wie kann ich nach dieser Anzahl gemeinsamer Freunde kalkulieren und bestellen?

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;

druckt

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

Ich habe es verstanden!

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;

druckt

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

Kann das bitte jemand bestätigen? Ist diese Abfrage optimal? Irgendwelche möglichen Leistungsprobleme bei der Erstellung als Ansicht?

Vielen Dank.

UPDATE ------------------------------------------------- -------------------------------------------

Ich habe eine Ansicht als erstellt

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;

und getestet.

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)

Antworten auf die Frage(1)

Ihre Antwort auf die Frage