Reputation: 287
So there is a friendship_request table:
+--------+----------+
| sender | receiver |
+--------+----------+
| 1 | 2 |
| 2 | 1 |
+--------+----------+
Two users are friends if both have sent each other a request.
I'm using PHP's array_intersect with arrays containing all the friends of each user to determine if they are connected through friends of friends.
i.e.
1 <--> 2 <--> 3
What is the most efficient way to find if two users have friends that have friends that are friends with each other. i.e.
+--------+----------+
| sender | receiver |
+--------+----------+
| 1 | 2 |
| 2 | 1 |
| 2 | 3 |
| 3 | 2 |
| 3 | 4 |
| 4 | 3 |
+--------+----------+
1 <--> 2 <--> 3 <--> 4
User 1 should know of his relationship with User 4.
PS: It's ok with PHP/pseudocode or MySQL
Edit: I do not want to create another table or views. I want to get the best solution using the resources described above.
Upvotes: 0
Views: 166
Reputation: 324
first create view detecting friendships:
CREATE VIEW friendship (friend1, friend2)
AS SELECT p1.id, p2.id from person as p1, person as p2
WHERE
(SELECT count(*) from friendship_request as fr1 WHERE
fr1.sender = p1.id AND fr1.receiver = p2.id) > 0
AND
(SELECT count(*) from friendship_request as fr2 WHERE
fr2.receiver = p1.id AND fr1.sender = p2.id) > 0
now query for 1st level connections is as simple as
SELECT p1.name, p1st.name, p2.name
FROM person as p1, person as p2, person as p1st,
friendship as fs1, friendship as fs2
WHERE p1.id = fs1.friend1
AND p2.id = fs2.friend1
AND fs1.frind2 = fs2.frind2
AND fs2.frind2 = p1st.id
for 2nd level connections:
SELECT DISTINCT p1.name, p2nd1.name, p2nd2.name, p2.name
FROM person as p1, person as p2, person as p2nd1, person as p2nd2,
friendship as fs1, friendship as fs2, friendship as fs2nd
WHERE p1.id = fs1.friend1
AND p2.id = fs2.friend1
AND fs1.frind2 = fs2nd.frind2
AND fs2.frind2 = fs2nd.frinend2
AND p2nd1.id = fs1.frind2
AND p2nd2.id = fs2.frind2
And so on.
Did not test but in any normal RDBMS should work :-)
Upvotes: 1
Reputation: 39
I would create a graph structure. An Adjacency List representation would work well. Then you can just run depth first search.
Upvotes: 0