Question

I'm developing a website wherein when a person adds another person as a friend, 2 entries are created. Let's say uid 1 adds uid 2 as a friend, the following rows are created in MySQL.

activity_id   uid1 uid2
     1         1     2
     2         2     1

uid 2 becomes friends with uid 3:

activity_id   uid1 uid2
     1         1     2
     2         2     1
     3         2     3
     4         3     2

What are the ways to get the mutual friends between uid 1 and uid 2? I'm using php and MySQL with no PDO experience (for now).

[EDIT] Okay, so I decided to organize/normalize the tables. The relationship only generates 1 row now. which makes the table:

activity_id   uid1 uid2
     1         1     2
     2         2     3
Was it helpful?

Solution

Looking at the table format from your other question, this should do what you want;

SELECT name FROM users u
JOIN friends f1
  ON u.uid = f1.uid OR u.uid = f1.fid
JOIN friends f2
  ON u.uid = f2.uid OR u.uid = f2.fid
WHERE (f1.uid=1 OR f1.fid=1) AND (f2.uid=3 OR f2.fid=3) 
  AND u.uid<>1 AND u.uid<>3;

Demo here.

OTHER TIPS

Assuming you have called your table 'friends'.

This query will find common friends for users 1 and 3.

SELECT a.uid2
  FROM friends a
    INNER JOIN friends b
       ON a.uid2 = b.uid2
  WHERE a.uid1 = 1
   AND b.uid1 = 3

Don't you think it might be a bit presumptuous to make 2 rows though? Maybe uid 2 doesn't really like uid 1 ? (OTY).

To find all common friends of uid 1 and uid 2:

SELECT t1.uid2
FROM   tbl t1
JOIN   tbl t2 USING (uid2)
WHERE  t1.uid1 = 1
AND    t2.uid1 = 2;

There is one special case, though: this query does not show whether 1 & 2 are friends!

BTW, your design seems a bit redundant. It should work with just one entry per friendship. (This query would have to be adapted for that, though.)

Basically this is another case of relational division. There are many different ways to skin this cat. Find quite under this related question - including performance testing and more information.


Query for updated question

Now there is only 1 row per friendship - a user can pop up in either column:

SELECT uid
FROM (
    SELECT uid2 AS uid FROM tbl WHERE uid1 = 1
    UNION ALL
    SELECT uid1        FROM tbl WHERE uid2 = 1
    ) u1
JOIN (
    SELECT uid2 AS uid FROM tbl WHERE uid1 = 2
    UNION ALL
    SELECT uid1        FROM tbl WHERE uid2 = 2
    ) u2 USING (uid)
$query="SELECT distinct(uid2) FROM `test` where uid1=$uid union select distinct(uid1) from test where uid2=$uid";
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top