tags:

views:

254

answers:

5

Currently I am in need to find the friends of friends in my application using PHP and MYSQL

For example : Database structure is like this. Table Name : tbl_friendlist

Ident   mem_id  friend_id  


1         2     1      

2         1     2  

3         1     3  

1         4     1     


5         1     8

How can i achieve this

I am able to get the Friends by

SELECT * FROM tbl_friendlist WHERE mem_id = 1.

By using this i am able to get my friends list. Now how can i get the friends of friends

Thanks in advance!

+3  A: 

So, breaking into steps -- you want to find all your friends, and then you want to find all of their friends. These are the two parts of your query (and subquery):

This is how you'd get a list of all your friends

SELECT friend_id
FROM tbl_friendlist
WHERE f.mem_id = 1

And so then you just wrap that in the second part:

SELECT f.friend_id
FROM tbl_friendlist f
WHERE f.mem_id IN (
    SELECT f2.friend_id
    FROM tbl_friendlist f2
    WHERE f2.mem_id = 1
)

You might also want to add some extra filters in there, eg:

SELECT DISTINCT f.friend_id
FROM tbl_friendlist f
WHERE f.mem_id IN (
    SELECT f2.friend_id
    FROM tbl_friendlist f2
    WHERE f2.mem_id = 1
) AND f.friend_id <> 1

This means you won't get duplicates, and you find yourself in your list of friends' friends.

nickf
You have renamed the tables in subqueries -> "WHERE f2.mem_id = 1"
Lukáš Lalinský
I think this leads to wrong output nick.. Because, according to the above table structure if i have the mem_id as 2 then, i need the output as friend_id 2,3,4,8. Because friend_id 1 is my friend. And his friends are obviously 2,3,4,8. So i need 2,3,4,8. But if i have the mem_id as 2 i just get the result freind_id 1. So kindly clear my clarification.. Excuse if anything i mentioned wrong..
Fero
Thanks Lukas. @Fero: that might have been because of the typo which lukas pointed out (changed now). However, from the look of your table, person 1 is not friends with person 4, unless friendships are symmetrical.
nickf
+2  A: 

i would do a subquery as well (my SQL is really rusty, but the query will look something like this)

SELECT * from tbl_friendlist where mem_id in (SELECT friend_id FROM tbl_friendlist WHERE mem_id = 1).
Andrew Keith
thanks keith, yours code produce the perfect output.. And thanks to all who helps me...
Fero
This works however I chose to upvote a few of the other answers since in large tables, the subquery causes a performance drawback that can be avoided by using a JOIN on itself.
Paulo
+2  A: 

If you need to find a way without subqueries you can try to do this by joining the table ON itself.

Idea, untested:

SELECT a.mem_id, b.mem_id AS secundaryfriends FROM tbl_friendlist AS a
JOIN tbl_friendlist AS b ON a.friend_id = mem_id;
tharkun
You should use just "JOIN", because you don't need a NULL if the friend has no friends, and also "b.mem_id AS secundaryfriends" should be "b.friend_id AS secundaryfriends".
Lukáš Lalinský
ah, INNER yes! but the other comment seems wrong.
tharkun
No, it isn't wrong: b.mem_id == a.friend_id, so you are selecting a list of a.mem_id, a.friend_id pairs.
Lukáš Lalinský
+1  A: 

Hmm, I think something like this may work:

SELECT 
   f1.friend_id, group_concat( f2.friend_id ) as f_of_f
FROM 
   tbl_friendlist f1
   LEFT JOIN 
   tbl_friendlist f2 ON ( f1.friend_id = f2.mem_id )
WHERE 
   f1.mem_id = 1
GROUP BY 
   f2.mem_id

This will give you the ids of the friends of friends as a comma separate value in f_of_f column.

Sabeen Malik
+2  A: 

The solution by nickf will work well, but I'd personally do this in a JOIN:

SELECT
    DISTINCT fof.friend_id
FROM
    tbl_friendlist f
    JOIN tbl_friendlist fof ON fof.mem_id=f.friend_id
WHERE
    f.mem_id = 1 AND fof.friend_id != 1;
Lukáš Lalinský