Nun, die einzige Abfrage, die bisher funktionieren könnte, ist die von Simon ... aber das ist echter Overkill - eine so komplexe böse Abfrage (2 Unterabfragen mit 2 Vereinigungen!) Für eine so einfache Sache, dass Sie ein Kopfgeld setzen müssen? :-) Und wenn Sie mehr als 1000 Benutzer haben, wird die Abfrage höllisch langsam sein - denken Sie daran, sie ist quadratisch und aufgrund von Vereinigungen in Unterabfragen würde kaum ein Index verwendet werden!
Ich würde vorschlagen, das Design noch einmal zu überdenken und zwei doppelte Zeilen für eine Freundschaft zuzulassen:
id Person1 Person2 status
1 1 2 friend
2 2 1 friend
3 1 3 friend
4 3 1 friend
Sie denken vielleicht, dass dies ineffizient ist, aber die folgende Vereinfachung ermöglicht es, die Abfrage in einfache Joins umzuschreiben:
select f1.Person2 as common_friend
from friends as f1 join friends as f2
using (Person2)
where f1.Person1 = '$id1' and f2.Person1 = '$id2'
and f1.status = 'friend' and f2.status = 'friend'
das wird verdammt schnell gehen! (Vergessen Sie nicht, Indizes für Person1,2 hinzuzufügen.) Ich habe zu einer ähnlichen Vereinfachung geraten (Umschreiben Unterabfragen zu Verknüpfungen) in einer anderen sehr unangenehmen Datenstruktur und hat die Abfrage beschleunigt von der Ewigkeit bis zum Blitz!
Was also wie ein großer Overhead aussah (2 Zeilen für eine Freundschaft), ist tatsächlich eine große Optimierung :-)
Außerdem werden Abfragen wie „Alle Freunde von X finden“ viel einfacher. Und es müssen keine Kopfgelder mehr ausgegeben werden :-)