SQL seleccionando personas que quizás conozcas

The question you're asking appears subjective and is likely to be closed.

No me sorprendí cuando vi arriba.horrible advertencia mientras yo estaba rellenando el campo del título.

Leo casi todos los hilos hablando defriends of friends omutual friends pero no estoy seguro de haber encontrado la solución correcta que quiero hacer.

Lo siento, no soy bueno en inglés ni en SQL.

¿Cómo puedo encontrar la respuesta correcta y no ser bueno en ambos idiomas?

Decidí que tengo que preguntar. No me decepcionaré pordown-votes o cualquieraduplication warnings.

Como quiero la respuesta, escribiré lo más sinceramente posible para cualquier problema similar que pueda ser ayudado.

Tengo una mesa para relaciones de amistad.

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

Amboscomposite primary keys también son claves foráneas dePLAYER mesa.

Pregunté y recibí respuestas de gente tan amable: "la gente se conoce".

Vista SQL para conocer de la tabla..

Y tengo una vista como esta.

ACQUAINTANCE (VIEW)
-----------------------------------
PLAYER_ID(PK,FK)   FRIEND_ID(PK,FK)
-----------------------------------
1                  2                 // 1 knows 2
2                  1                 // 2 knows 1

Como se habrá notado, la lógica de negocios de esta relación tiene dos propósitos.

Un jugador puede decir que conoce a alguien más.Cuando ambas personas dicen que se conocen, se les puede decir como conocidos.

Y, ahora, quiero saber si hay alguna buena manera de

Seleccionando otros PLAYER_IDsCon el JUGADOR dado (PLAYER_ID) (digamos 1)¿Cuál de ellos es uno de los "amigos de los amigos directos de JUGADOR"?Que cada uno no es el JUGADOR (excluyendo 1 -> 2 -> 1)Cada uno de los cuales no es el amigo directo del JUGADOR (excluyendo 3 de 1 -> 2 -> 3 por 1 -> 3)Ordenar por número de amigos mutuos si es posible.

Creo que la respuesta de Justin Niessner en"gente que puedes conocer" consulta SQL Es el camino más cercano que debo seguir.

Gracias por adelantado.

Cerraré el hilo si este tema está realmente duplicado y no es necesario.

ACTUALIZACIÓN ------------------------------------------------- -------------

para el comentario de Raphaël Althauswhose name is same with my future daughter (es el nombre del niño?),

3 es un candidato parafriends of friends of 1 porque

1 knows 2
2 knows 3

pero excluido porque

1 already knows 3

Básicamente quiero servir para elgiven player la

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

Con la tabla de arriba

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.

Gracias.

ACTUALIZACIÓN ------------------------------------------------- --------------------

Creo que debo intentarlo paso a paso a partir de lo que he aprendido.FROM HERE WITH VARIOUS PEOPLE incluso si no es la respuesta correcta. Por favor, hágamelo saber si estoy haciendo algo mal.

En primer lugar, permítanme unirme a la tabla FRIEND.

SELECT *
FROM FRIEND F1 INNER JOIN FRIEND F2 ON F1.FRIEND_ID = F2.PLAYER_ID

huellas dactilares

+-----------+-----------+-----------+-----------+
| 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 |
+-----------+-----------+-----------+-----------+

F2.FRIEND_ID solamente

SELECT F2.FRIEND_ID
FROM FRIEND F1 INNER JOIN FRIEND F2 ON F1.FRIEND_ID = F2.PLAYER_ID

huellas dactilares

+-----------+
| FRIEND_ID |
+-----------+
|         1 |
|         3 |
|         4 |
|         5 |
|         5 |
|         2 |
|         3 |
|         5 |
+-----------+

solo para 1

SELECT F2.FRIEND_ID
FROM FRIEND F1 INNER JOIN FRIEND F2 ON F1.FRIEND_ID = F2.PLAYER_ID
WHERE F1.PLAYER_ID = 1;

huellas dactilares

+-----------+
| FRIEND_ID |
+-----------+
|         1 |
|         3 |
|         4 |
|         5 |
|         5 |
+-----------+

no 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;

huellas dactilares

+-----------+
| FRIEND_ID |
+-----------+
|         3 |
|         4 |
|         5 |
|         5 |
+-----------+

no conocidos directamente

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);

huellas dactilares

+-----------+
| FRIEND_ID |
+-----------+
|         4 |
|         5 |
|         5 |
+-----------+

Creo que estoy llegando allí.

ACTUALIZACIÓN ------------------------------------------------- ----------------

Siguiendo caminos agregados

1 -> 100 -> 400
1 -> 200 -> 400
1 -> 300 -> 400

Y la última consulta se imprime (otra vez).

+-----------+
| FRIEND_ID |
+-----------+
|         4 |
|         5 |
|         5 |
|       400 |
|       400 |
|       400 |
+-----------+

por fin, tengo los candidatos: 4, 5, 400

Poniendodistinct Seguramente trabajar para el objetivo principal.

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);

huellas dactilares

+-----------+
| FRIEND_ID |
+-----------+
|         4 |
|         5 |
|       400 |
+-----------+

Y, ahora, ordenar por recuentos mutuos necesarios.

Aquí viene el número de amigos mutuos para cada candidato.

+-----------+
| 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)
+-----------+

¿Cómo puedo calcular y ordenar por el número de amigos mutuos?

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;

huellas dactilares

+-----------+----------+
| FRIEND_ID | COUNT(*) |
+-----------+----------+
|         4 |        1 |
|         5 |        2 |
|       400 |        3 |
+-----------+----------+

¡Entiendo!

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;

huellas dactilares

+-----------+-----+
| FRIEND_ID | MFC |
+-----------+-----+
|       400 |   3 |
|         5 |   2 |
|         4 |   1 |
+-----------+-----+

¿Alguien por favor puede confirmar esto? ¿Es esa consulta óptima? ¿Algún posible problema de rendimiento al hacerlo como una vista?

Gracias.

ACTUALIZACIÓN ------------------------------------------------- -------------------------------------------

He creado una vista como

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;

y probado.

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)

Respuestas a la pregunta(1)

Su respuesta a la pregunta