SQL selecionando pessoas que você pode conhecer

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

Eu não fiquei surpreso quando vi acimaaviso horrível enquanto eu estava preenchendo o campo do título.

Eu li quase todos os tópicos falando sobrefriends of friends oumutual friends mas não tenho certeza se encontrei a solução correta que quero fazer.

Me desculpe, eu não sou bom em inglês nem em SQL.

Como posso encontrar a resposta certa, apesar de não ser bom em ambos os idiomas?

Eu decidi que tenho que perguntar. Eu não vou me decepcionar pordown-votes ou qualquerduplication warnings.

Como eu quero a resposta, vou escrever da maneira mais sincera possível, para que quaisquer outros problemas semelhantes possam ser ajudados.

Eu tenho uma mesa para relações de amizade.

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 também são chaves estrangeiras dePLAYER mesa.

Eu perguntei e fui respondido por pessoas tão agradáveis ​​que "as pessoas se conhecem".

Visualização SQL para o conhecimento da tabela.

E eu tenho uma visão como essa.

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

Como você pode notar, a lógica de negócios desse relacionamento segue dois propósitos.

Um jogador pode dizer que conhece alguém.Quando as duas pessoas dizem que se conhecem, elas podem ser ditas como conhecidas.

E agora, eu quero saber se há algum bom caminho para

Selecionando outros PLAYER_IDsCom determinado JOGADOR (PLAYER_ID) (digamos 1)Qual deles é um dos 'amigos dos amigos diretos do JOGADOR'Qual não é o próprio PLAYER (excluindo 1 -> 2 -> 1)Que cada um não é amigo direto do JOGADOR (excluindo 3 de 1 -> 2 -> 3 por 1 -> 3)Ordenar por número de amigos em comum, se possível.

Eu acho que a resposta de Justin Niessner em"pessoas que você talvez conheça" consulta sql é o caminho mais próximo que devo seguir.

Desde já, obrigado.

Vou fechar o tópico se esse assunto for realmente duplicado e não for necessário.

UPDATE ------------------------------------------------- -------------

para o comentário de Raphaël Althauswhose name is same with my future daughter (é o nome do menino?)

3 é um candidato parafriends of friends of 1 Porque

1 knows 2
2 knows 3

mas excluídos porque

1 already knows 3

Basicamente eu quero servir para ogiven player a

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

Com tabela acima

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.

Obrigado.

UPDATE ------------------------------------------------- --------------------

Eu acho que devo tentar passo a passo sozinha pelo que eu aprendiFROM HERE WITH VARIOUS PEOPLE mesmo que não seja a resposta certa. Por favor, deixe-me saber se estou fazendo algo errado.

Primeiro de tudo, deixe-me juntar-me à própria tabela AMIGO.

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

impressões

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

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

impressões

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

por apenas 1

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

impressões

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

não 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;

impressões

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

não 1s conhecidos diretos

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

impressões

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

Eu acho que estou chegando lá.

UPDATE ------------------------------------------------- ----------------

Seguindo os caminhos adicionados

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

E a última consulta é impressa (novamente)

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

enfim, consegui os candidatos: 4, 5, 400

Colocandodistinct certamente trabalhar para o 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);

impressões

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

E agora, encomendar por contagens mútuas necessárias.

Aí vem o número de amigos em comum 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)
+-----------+

Como posso calcular e encomendar pelo número de amigos em comum?

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;

impressões

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

Deixa comigo!

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;

impressões

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

Alguém pode confirmar isso? Essa consulta é ideal? Algum problema de desempenho possível quando ele é visto?

Obrigado.

UPDATE ------------------------------------------------- -------------------------------------------

Eu criei uma visão 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;

e testado.

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)

questionAnswers(1)

yourAnswerToTheQuestion