MySQL Query to find friends and number of mutual friends

前端 未结 3 428
盖世英雄少女心
盖世英雄少女心 2020-12-28 11:16

I have looked through the questions but I cant find anything that does exactly what I need and I can\'t figure out how to do it myself.

I have 2 tables, a user table

3条回答
  •  孤城傲影
    2020-12-28 11:51

    Mutual friends can be found by joining the friend_links table to itself on the friend_id field like so:

    SELECT *
    FROM friend_links f1 INNER JOIN friend_links f2
      ON f1.friend_id = f2.friend_id
    WHERE f1.user_id = $person1
      AND f2.user_id = $person2
    

    But bear in mind that this, in its worst case, is essentially squaring the number of rows in the friend_links table and can pretty easily jack up your server once you have a non-trivial number of rows. A better option would be to use 2 sub-queries for each user and then join the results of those.

    SELECT *
    FROM (
      SELECT *
      FROM friend_links
      WHERE user_id = $person1
    ) p1 INNER JOIN (
      SELECT *
      FROM friend_links
      WHERE user_id = $person1
    ) p2
      ON p1.friend_id = p2.friend_id
    

    Also, you can simplify your friend_links table by removing the surrogate key link_id and just making (user_id,friend_id) the primary key since they must be unique anyway.


    Edit:

    How would this be applied to the original query of searching for users that aren't already friends, I would like to do both in a single query if possible?

    SELECT f2.user_id, COUNT(*) 'friends_in_common'
    FROM friend_links f1 LEFT JOIN friend_links f2
      ON f1.friend_id = f2.friend_id
    WHERE f1.user_id = $person
    GROUP BY f2.user_id
    ORDER BY friends_in_common DESC
    LIMIT $number
    

    I am also thinking that the user_id constraints can be moved from the WHERE clause into the JOIN conditions to reduce the size of the data set created by the self-join and preclude the use of subqueries like in my second example.

提交回复
热议问题