简体   繁体   中英

Get users which I have friends in common

There are 2 sql tables:

1) "users" with the following structure and data:

user_id, user_name

 1, John
 2, Mike
 3, Chris
 4, Paul
 5, Kelly
 6, Kevin

2) "userfriends" which cotains friendship relations, with the following structure and data:

userfriends_user_id, userfriends_friend_id

 1, 2 => [ John is friend with Mike ]
 2, 3 => [ Mike is friend with Chris]
 2, 4 => [ Mike is friend with Paul ]
 5, 1 => [ Kelly is friend with John]
 6, 5 => [ Kevin is friend with Kelly]

I want to make a SELECT (user_name, user_id) to get those users where John have common friends with, so the output should be Chris, Paul, Kevin. Can this be done in only ONE select statement ?

You can do this by getting all the friends of your friends. This requires a join from the userfriends table back to itself.

Then, just look at the the "friends of friends" that appear more than once. You can do this with group by and having :

select uff.userfriends_friend_id
from userfriends uf join
     userfriends uff
     on uf.userfriends_friend_id = uff.userfriends_user_id
where uf.userfriends_user_id = 1
group by uff.userfriends_friend_id
having count(*) > 1;

Well, I still don't know if I am thinking too complicated right now. Here is what I've come up with:

select * from users
where user_id in
(
  select user1_id
  from
  ( -- users except John and their friends (again except John)
    select userfriends_user_id as user1_id, userfriends_friend_id as user2_id 
    from userfriends where userfriends_user_id != 1 and userfriends_friend_id != 1
    union 
    select userfriends_friend_id as user1_id, userfriends_user_id as user2_id 
    from userfriends where userfriends_user_id != 1 and userfriends_friend_id != 1
  ) others
  where user2_id in
  ( -- friends of John's
    select userfriends_user_id from userfriends where userfriends_friend_id = 1
    union
    select userfriends_friend_id from userfriends where userfriends_user_id = 1
  )
);

Here is the SQL fiddle: http://sqlfiddle.com/#!2/338d87/1 .

TEST this query:

SELECT * FROM users
WHERE user_id IN
(
    SELECT uf.userfriends_friend_id AS CommonId
    FROM userfriends uf, 
        (
            SELECT uf2.userfriends_friend_id
            FROM userfriends uf2
            WHERE uf2.userfriends_user_id = 1
        ) A
    WHERE uf.userfriends_user_id = A.userfriends_friend_id

    UNION

    SELECT uf.userfriends_user_id  AS CommonId
    FROM userfriends uf, 
        (
            SELECT uf2.userfriends_user_id
            FROM userfriends uf2
            WHERE uf2.userfriends_friend_id = 1
        ) A
    WHERE uf.userfriends_friend_id = A.userfriends_user_id
)

I tested SQLfiddle provided by @Thorsten Kettner. It works. Output is correct. Thanks @Thorsten Kettner!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM