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-vote
s oder irgendwelcheduplication warning
s.
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)