Conclusão heurística de amizade em SQL

Saudações!

Não tinha muita idéia do que postar, mas lembrei de uma query que eu tinha feito, talvez seja útil para demonstração de péssimo uso de queries, sei lá. :D

O motivo deste título, embora pareça estranho, retrata a situação a qual a query foi destinada. Vamos começar a entender o título?

A heurística (do greco ευρίσκω, heurísko, literalmente "descubro" ou "acho") é uma parte da epistemologia e do método científico.

A etimologia da palavra heurística é a mesma que a palavra eureka, cuja exclamação se atribui a Arquimedes no conhecido episódio da descoberta de como medir o volume de um objeto irregular utilizando água.
[...]
Define-se procedimento heurístico como um método de aproximação das soluções dos problemas, que não segue um percurso claro mas se baseia na intuição e nas circunstâncias a fim de gerar conhecimento novo.
[1]

E no mundo da computação...

Denomina-se 'heurística' à capacidade de um sistema fazer inovações e desenvolver técnicas de forma imediata e positivas para um determinado fim. [1]

- Tá OK, mas cadê a query? Onde entra a amizade nisso? O.o

Ah, a amizade. Pois bem, a situação é a seguinte: Tendo uma tabela com Id do usuário e Id do amigo, como poderia ser obtido possíveis amigos, os quais atualmente não estão associados como seus amigos na tabela? A idéia foi apresentada a mim pelo amigo Pedro Menezes, não contestei a tal, pois achei até legal sinal. :D

Enfim, vamos analisar os dados e por fim, ver a bomba, digo, a query. :D

mysql> select * from amigos;
+---------+----------+
| id_user | id_amigo |
+---------+----------+
|       1 |        2 | 
|       1 |        3 | 
|       1 |        4 | 
|       1 |        5 | 
|       2 |       10 | 
|       3 |       10 | 
|       4 |       10 | 
|      10 |        4 | 
+---------+----------+

Como podemos ver, o carinha do ID 1 é amigo do 2, 3, 4 e 5. E por sua vez o 2, 3 e 4 são amigos do 10. Sendo este um desconhecido pra você até então, seria este 10 um possível amigo seu? Bem, a lógica apresentada, foi justamente essa, quando 3 ou mais amigos possuem um amigo em comum, que ainda não é meu amigo, então este é um provável amigo meu.

Sacou? ou como diria os portugueses, estás a perceber?

A query que julga obter tais prováveis camaradas desconhecidos, é a seguinte:

SELECT amigos_de_amigos.id_amigo
FROM (
	/* amigos dos seus amigos que não são seus amigos */
	SELECT amigos.id_amigo
	FROM (
			/* seus amigos */
			SELECT id_amigo
			FROM amigos
			WHERE id_user = 1
	) meus_amigos 
	RIGHT JOIN amigos 
		ON amigos.id_user = meus_amigos.id_amigo
	WHERE meus_amigos.id_amigo IS NOT NULL AND
		/* o amigo do amigo que não é seu amigo */
		NOT EXISTS (
			SELECT 1
			FROM amigos a
			WHERE id_user = 1 AND a.id_amigo = amigos.id_amigo
		)
) amigos_de_amigos
GROUP BY amigos_de_amigos.id_amigo
HAVING COUNT(*) > 2;

A query é bem simples, dispensa explicações, correto? Então...
1, 2, 3... Testando:

mysql> SELECT amigos_de_amigos.id_amigo FROM (  SELECT amigos.id_amigo FROM (  SELECT id_amigo FROM amigos WHERE id_user = 1 ) meus_amigos  RIGHT JOIN amigos  ON amigos.id_user = meus_amigos.id_amigo WHERE meus_amigos.id_amigo IS NOT NULL AND  NOT EXISTS ( SELECT 1 FROM amigos a WHERE id_user = 1 AND a.id_amigo = amigos.id_amigo ) ) amigos_de_amigos GROUP BY amigos_de_amigos.id_amigo HAVING COUNT(*) > 2;
+----------+
| id_amigo |
+----------+
|       10 | 
+----------+
1 row in set (0.00 sec)

E é isso aí.

PS: Tá, tá bom, eu não pensei em peformance mesmo não. :-)

[1] - http://pt.wikipedia.org/wiki/Heurística

Legal eim... Minha dúvida

Legal eim...

Minha dúvida é...

Como eu poderia fazer uma query de amigos em comum?

Por exemplo entrei no perfil do amigo X e queria saber quais os amigos meus que também são amigo dele?

ABs,

halan.

Aí é mais simples ainda.

Aí é mais simples ainda. Exemplo:

SELECT A.id_amigo
  FROM amigos A
  WHERE A.id_user = ID_DO_AMIGO
    AND EXISTS (
    SELECT 1 
       FROM amigos B
       WHERE B.id_user = MEU_ID
         AND B.id_amigo = A.id_amigo)

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options