[英]Mutual friends sql
我在共同的朋友身上看到了多个SO帖子,但我在我的数据库中构建了我的朋友表,以便没有重复项,例如(1,2)而不是(2,1)
Create Table Friends(
user1_id int,
user2_id int
);
然后是一个约束,以确保user1 id始终小于user2 id,例如4 <5
我看到建议找到共同的朋友可以使用连接找到它,所以这就是我所拥有的,但我认为这是错误的,因为如果我用我的数据库中的数据计算查询的实际结果,我会得到不同的结果
select f1.user1_id as user1, f2.user1_id as user2, count(f1.user2_id) as
mutual_count from Friends f1 JOIN Friends f2 ON
f1.user2_id = f2.user2_id AND f1.user1_id <> f2.user1_id GROUP BY
f1.user1_id, f2.user1_id order by mutual_count desc
我可以看到有三种连接方案。
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语句)和更低成本的执行计划。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.