JOINを使用して、幅優先、最短経路検索を使用して検索を実行する方法は次のとおりです。答えを見つけるためにMySQLを使用しているため、このアルゴリズムには魔法はありません。また、あらゆる種類のヒューリスティックや最適化を使用する高度な検索アルゴリズムは組み込まれていません。
私の「友達」テーブルには一方向の関係があるので、「1から2」と「2から1」の両方が保存されるという意味で重複があります。実装が明らかになるため、is_activeも除外します:
データは次のとおりです:
member_id friend_id
1 2
1 3
1 4
2 1
2 3
2 5
2 6
3 2
3 1
4 1
5 2
6 2
6 7
7 6
7 8
8 7
メンバー1を選択しましたが、友達1人と友達7人、友達の友達などを尋ねています。 0のカウントはいいえを意味し、1のカウントははいを意味します。
SELECT COUNT(*)
FROM friends f1
WHERE f1.member_id = 1
AND f1.friend_id = 7
いいえの場合、彼らは友人の友人ですか?
SELECT COUNT(*)
FROM friends f1
JOIN friends f2
ON f2.member_id = f1.friend_id
WHERE f1.member_id = 1
AND f2.friend_id = 7
いいえの場合、友人の友人の友人ですか?
SELECT COUNT(*)
FROM friends f1
JOIN friends f2
ON f2.member_id = f1.friend_id
JOIN friends f3
ON f3.member_id = f2.friend_id
WHERE f1.member_id = 1
AND f3.friend_id = 7
など...
3番目のクエリは、パス「1から2」、「2から6」、および「6から7」を検索し、1のカウントを返します。
各クエリは(結合の数が多いために)コストが高くなるため、ある時点で検索を制限することをお勧めします。クールな点の1つは、この検索が両端から中央に向かって機能することです。これは、最短経路検索に推奨される1つの単純な最適化です。
メンバー1の相互の友達のおすすめを見つける方法は次のとおりです。
SELECT f2.friend_id
FROM friends f1
JOIN friends f2
ON f2.member_id = f1.friend_id
LEFT JOIN friends f3
ON f3.member_id = f1.member_id
AND f3.friend_id = f2.friend_id
WHERE f1.member_id = 1
AND f2.friend_id <> f1.member_id // Not ourself
AND f3.friend_id IS NULL // Not already a friend