The question you're asking appears subjective and is likely to be closed.
SQL選擇了你可能認識
當我在上面可怕的警告看到當我在標題字段填寫我並不感到驚訝。
我幾乎讀過所有關於friends of friends
或mutual friends
的帖子,但我不確定我是否找到了我想要的正確解決方案。
對不起,我不擅長英語和SQL。
如何在兩種語言都不好的情況下找到正確的答案?
我決定我不得不問。我不會因爲down-vote
或任何duplication warning
而讓自己失望。
正如我想要的答案,我會盡可能真誠地寫下來,因爲任何進一步的類似問題都可以得到幫助。
我有一張朋友關係表。
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
兩個composite primary keys
也從PLAYER
表的外鍵。
我問,並從這麼好的人回答「人們相互認識」。
SQL view for acquaintance from table。
我有這樣的看法。
ACQUAINTANCE (VIEW)
-----------------------------------
PLAYER_ID(PK,FK) FRIEND_ID(PK,FK)
-----------------------------------
1 2 // 1 knows 2
2 1 // 2 knows 1
正如您可能會注意到的,這種關係的業務邏輯有以下兩個目的。
- 一個玩家可以說他或她知道別人。
- 當兩個人都說他們彼此認識時,他們可以說是熟人。
而且,現在,我想知道的是有
- 選擇其他PLAYER_IDs
- 按照給定的播放器(PLAYER_ID)什麼好的方法(比如1)
- 它們各自的一個`給定PLAYER的直接朋友的朋友'
- 哪一個不是玩家本人(不包括1 - > 2 - > 1)
- 哪一個不是玩家的直接朋友(不包括3個1→2→3→1→3)
- 如果可能,按共同朋友的數量排序。
我認爲Justin Niessner在"people you may know" sql query的回答是我必須遵循的最接近的路徑。
在此先感謝。
如果此主題真的重複且不必要,我將關閉該主題。
UPDATE --------------------------------------------- -----------------
爲拉斐爾奧爾索斯的評論whose name is same with my future daughter
(是男孩的名字?),
3是一個候選friends of friends of 1
因爲
1 knows 2
2 knows 3
但排除在外,因爲
1 already knows 3
基本上我想以服務爲given player
的
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
有了上面的表格
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.
謝謝。
UPDATE --------------------------------------------- ------------------------
我想我必須自己從我學過的東西中一步一步地學習FROM HERE WITH VARIOUS PEOPLE
即使它不是正確答案。 請讓我知道如果我做錯了什麼。
首先,讓我自己加入FRIEND表本身。
SELECT *
FROM FRIEND F1 INNER JOIN FRIEND F2 ON F1.FRIEND_ID = F2.PLAYER_ID
打印
+-----------+-----------+-----------+-----------+
| 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僅
SELECT F2.FRIEND_ID
FROM FRIEND F1 INNER JOIN FRIEND F2 ON F1.FRIEND_ID = F2.PLAYER_ID
打印
+-----------+
| FRIEND_ID |
+-----------+
| 1 |
| 3 |
| 4 |
| 5 |
| 5 |
| 2 |
| 3 |
| 5 |
+-----------+
1只
SELECT F2.FRIEND_ID
FROM FRIEND F1 INNER JOIN FRIEND F2 ON F1.FRIEND_ID = F2.PLAYER_ID
WHERE F1.PLAYER_ID = 1;
打印
+-----------+
| FRIEND_ID |
+-----------+
| 1 |
| 3 |
| 4 |
| 5 |
| 5 |
+-----------+
不是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;
打印
+-----------+
| FRIEND_ID |
+-----------+
| 3 |
| 4 |
| 5 |
| 5 |
+-----------+
不爲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
AND F2.FRIEND_ID NOT IN (SELECT FRIEND_ID FROM FRIEND WHERE PLAYER_ID = 1);
打印
+-----------+
| FRIEND_ID |
+-----------+
| 4 |
| 5 |
| 5 |
+-----------+
我想我到了那裏。
UPDATE --------------------------------------------- --------------------
以下路徑添加
1 -> 100 -> 400
1 -> 200 -> 400
1 -> 300 -> 400
和上次查詢打印(再次)
+-----------+
| FRIEND_ID |
+-----------+
| 4 |
| 5 |
| 5 |
| 400 |
| 400 |
| 400 |
+-----------+
在最後,我得到了候選人:4,540
把distinct
當然對於工作的首要目標
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);
打印
+-----------+
| FRIEND_ID |
+-----------+
| 4 |
| 5 |
| 400 |
+-----------+
而且,現在,通過在需要相互計數訂貨。
這裏是每個候選人的共同朋友的數量。
+-----------+
| 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)
+-----------+
如何計算和訂購這些共同朋友的數量?
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;
打印
+-----------+----------+
| FRIEND_ID | COUNT(*) |
+-----------+----------+
| 4 | 1 |
| 5 | 2 |
| 400 | 3 |
+-----------+----------+
我知道了!
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;
打印
+-----------+-----+
| FRIEND_ID | MFC |
+-----------+-----+
| 400 | 3 |
| 5 | 2 |
| 4 | 1 |
+-----------+-----+
可有人請證實?該查詢是否最優?將它視爲視圖時可能出現任何性能問題?
謝謝。
UPDATE --------------------------------------------- -----------------------------------------------
我創建了一個視圖爲
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;
並進行了測試。
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)
點1 => 3不是我的(差)的眼睛說清楚。你可以提供一組數據和你想要檢索的確切結果,或者(如果你的數據集足夠的話,只是你想要的結果)。 –
您是否期望生成的SQL返回4? –
值得一提的是,您正在應用一種稱爲圖論的數學分支。如果你在這個問題上做的不僅僅是一小撮的工作,你應該明智地閱讀一本關於這個問題的書。它有許多微妙之處。有關如何學習該材料的建議,請嘗試使用programmers.stackexchange.com –