Eh bien, la seule requête qui pourrait fonctionner jusqu'à présent est celle de Simon... mais c'est vraiment exagéré - une requête aussi complexe et désagréable (2 sous-requêtes avec 2 unions !) Pour une chose si simple que vous devez placer une prime ? :-) Et si vous avez plus de 1000 utilisateurs, la requête sera lente comme l'enfer - rappelez-vous, c'est quadratique, et en raison des unions dans les sous-requêtes, pratiquement aucun index ne sera utilisé !
Je suggérerais de repenser à nouveau le design et d'autoriser 2 lignes en double pour une amitié :
id Person1 Person2 status
1 1 2 friend
2 2 1 friend
3 1 3 friend
4 3 1 friend
Vous pourriez penser que c'est inefficace mais la simplification suivante permettra de réécrire la requête en jointures simples :
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'
qui sera rapide comme l'enfer! (N'oubliez pas d'ajouter des indices pour Person1,2.) J'ai conseillé une simplification similaire (réécriture sous-requêtes aux jointures) dans une autre structure de données très désagréable et cela a accéléré la requête de l'éternité au blitz instantané !
Donc, ce qui aurait pu ressembler à un gros surcoût (2 lignes pour une amitié) est en fait une grosse optimisation :-)
En outre, cela rendra les requêtes telles que "trouver tous les amis de X" beaucoup plus faciles. Et plus aucune prime n'aura besoin d'être dépensée :-)