相互的朋友sql

时间:2016-10-12 22:22:22

标签: mysql

我在共同的朋友身上看过多篇SO帖子,但我已经在我的数据库中构建了我的朋友表,这样就没有重复的内容,例如(1,2)而不是(2,1)

PostFlush

然后是一个约束,以确保user1 id始终小于user2 id,例如4< 5

Mutual friends sql with join (Mysql)

我看到建议找到共同的朋友可以通过联接找到它,所以这就是我所拥有的,但我认为这是错误的,因为如果我使用查询的实际结果计算我的数据库中的数据我得到了不同的结果

    Create Table Friends(
      user1_id int, 
      user2_id int
    );

1 个答案:

答案 0 :(得分:0)

我可以看到三种连接方案。

1 -> 2 -> 3    (mutual friend id between other IDs)    
2 -> 3 -> 1    (mutual friend id > other IDs)    
2 -> 1 -> 3    (mutual friend id < other IDs)    

可以使用此谓词解析此 ...

ON f1.user1_id IN (f2.user1_id, f2.user2_id)
OR f1.user2_id IN (f2.user1_id, f2.user2_id)
AND <not joining the row to Itself>

但这将完全搞乱优化者使用索引的能力。

所以,我会结合多个查询。

(伪代码,因为我正在打电话)

SELECT u1, u2, COUNT(*) FROM
(
    SELECT f1.u1, f2.u2 FROM f1 INNER JOIN f2 ON f1.u2 = f2.u1 AND f1.u1 <> f2.u2
    UNION ALL
    SELECT f1.u1, f2.u1 FROM f1 INNER JOIN f2 ON f1.u2 = f2.u2 AND f1.u1 <> f2.u1
    UNION ALL
    SELECT f1.u2, f2.u2 FROM f1 INNER JOIN f2 ON f1.u1 = f2.u1 AND f1.u2 <> f2.u2
) all_combinations
GROUP BY u1, u2

然后,每个单独的查询都能够充分利用索引。 (在u1上添加一个索引,在u2上添加另一个索引

结果应该是更少深奥的代码(使用相当长的CASE语句)和更低成本的执行计划。