簡體   English   中英

相互的朋友sql

[英]Mutual friends sql

我在共同的朋友身上看到了多個SO帖子,但我在我的數據庫中構建了我的朋友表,以便沒有重復項,例如(1,2)而不是(2,1)

    Create Table Friends(
      user1_id int, 
      user2_id int
    );

然后是一個約束,以確保user1 id始終小於user2 id,例如4 <5

互助的朋友sql(Mysql)

我看到建議找到共同的朋友可以使用連接找到它,所以這就是我所擁有的,但我認為這是錯誤的,因為如果我用我的數據庫中的數據計算查詢的實際結果,我會得到不同的結果

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM