Bem, a única consulta que pode funcionar até agora é a de Simon... mas isso é um verdadeiro exagero - uma consulta tão complexa e desagradável (2 subconsultas com 2 uniões!) para uma coisa tão simples que você precisa colocar uma recompensa? :-) E se você tiver mais de 1000 usuários, a consulta será lenta como o inferno - lembre-se, é quadrática e, devido a uniões nas subconsultas, dificilmente qualquer índice seria usado!
Sugiro repensar o design novamente e permitir 2 linhas duplicadas para uma amizade:
id Person1 Person2 status
1 1 2 friend
2 2 1 friend
3 1 3 friend
4 3 1 friend
Você pode pensar que isso é ineficiente, mas a simplificação a seguir permitirá reescrever a consulta para junções 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'
que será rápido como o inferno! (Não se esqueça de adicionar índices para Person1,2.) Aconselhei uma simplificação semelhante (reescrever subconsultas para junções) em outra estrutura de dados muito desagradável e acelerou a consulta da eternidade ao instante-blitz!
Então, o que pode parecer uma grande sobrecarga (2 linhas para uma amizade) é na verdade uma grande otimização :-)
Além disso, tornará as consultas como "encontrar todos os amigos de X" muito mais fáceis. E não será necessário gastar mais recompensas :-)