2015-10-16 107 views
2

我有兩個帶有用戶ID的表,另一個表通過存儲兩個用戶ID來表示兩個用戶之間的關係。如何計算兩個用戶之間的相互關係,並將相互關係定義爲兩個用戶都與之有關係的用戶數。SQL查詢計數兩個表之間的關係

例如,如果我有:

3 - 4 
1 - 4 
3 - 6 
5 - 6 
2 - 6 
1 - 6 

我希望我的查詢返回(按順序)

User1 User2 MutualCount 
    1 | 3 | 2 
    2 | 3 | 1 
    1 | 2 | 1 
    1 | 5 | 1 
    2 | 5 | 1 
    4 | 6 | 1 
    3 | 5 | 1 

等等......

我想一些User1/User2的內部連接,但我無法弄清楚ON部分是如何工作的,也不知道如何存儲和返回計數。

我很感激任何幫助!

我用這個來提取所有的任意兩個用戶的相互關係,但我一直沒能想出一個辦法做到這一點爲所有用戶

SELECT b.userid, 
FROM user b, user c, relation f 
WHERE c.user_id = <user id here> 
AND (c.user_id = f.user1_id OR c.user_id = f.user2_id) 
AND (b.user_id = f.user1_id OR b.user_id = f.user2_id) 
INTERSECT 
SELECT b.user_id 
FROM user b, user c, relation f 
WHERE c.user_id = <user id here> 
AND (c.user_id = f.user1_id OR c.user_id = f.user2_id) 
AND (b.user_id = f.user1_id OR b.user_id = f.user2_id); 
+1

那麼到目前爲止你已經嘗試過了嗎? – Japongskie

+0

請定義**相互數**。 – DarkKnight

+0

互相計數是與用戶1和用戶2之間的普通用戶關係的數量。 – shawnt00

回答

0

編輯:儘管應該馬上明白它無法工作,但我在出門時首先嚐試了這一點。 (例如沒有值的列1和2是完全脫離,可能從來沒有匹配。)

也許這?:

select 
    case when mr1.user1 < mr2.user2 then mr1.user1 else mr2.user2 end as User1, 
    case when mr1.user1 < mr2.user2 then mr2.user2 else mr1.user1 end as User2, 
    count(*) as MutualCount 
from 
    mr mr1 inner join mr mr2 on mr1.user2 = mr2.user1 
group by 
    mr1.user1, mr2.user2 
order by 
    case when mr1.user1 < mr2.user2 then mr1.user1 else mr2.user2 end, 
    case when mr1.user1 < mr2.user2 then mr2.user2 else mr1.user1 end 

@Joel問題比它一開始似乎有點麻煩。普通用戶可能在兩列中的任何一列中,我們都沒有處理。這也正是case表達進來,我相信一個正確的解決辦法是下面:

select 
    mr1.user1, 
    case when mr1.user2 <> mr2.user1 then mr2.user1 else mr2.user2 end as user2, 
    count(*) as MutualCount 
from 
    mr mr1 inner join mr mr2 
     on  mr1.user2 in (mr2.user1, mr2.user2) /* match either user... */ 
      and mr1.user1 <> mr2.user1 /* ...but not when it's the same row */ 
where 
    mr1.user1 < case when mr1.user2 <> mr2.user1 then mr2.user1 else mr2.user2 end 
group by 
    mr1.user1, 
    case when mr1.user2 <> mr2.user1 then mr2.user1 else mr2.user2 end 
order by 
    mr1.user1, 
    case when mr1.user2 <> mr2.user1 then mr2.user1 else mr2.user2 end 

http://sqlfiddle.com/#!3/7e652/15

您也可以使用同樣的加入,找到共同的用戶。只需刪除group bycount()

+0

我認爲這隻能解決他們的一個子集,但它很接近。 – jordan2321

0
SELECT user1Id, user2ID, COUNT(*) MutualCount 
FROM UserVsUser 
GROUP BY user1Id, user2ID 
ORDER BY MutualCount DESC 

UserVsUser是表示兩個用戶之間關係的表。

0

這將讓你最那裏的方式:

SELECT r1.user1_id As User1, r2.user1_id As User2, count(*) As MutualCount 
FROM relation r1 
INNER JOIN relation r2 ON r1.user2_id = r2.user2_id AND r1.user1_id < r2.user1_id 
GROUP BY r1.user1_Id, r2.user1_id 
ORDER BY count(*) DESC; 

這將產生類似的結果,以目前接受的答案,但用更少的代碼和加快執行速度。

SQLFiddle

我從樣本數據爲什麼對(1,3)具有2的計數,以及爲什麼對(2,3)(1,2)理解,和(1,5)所有產生1。然而,不知從樣品明白爲什麼(1,4)(1,6),或(3,4)顯示在結果可言,尤其是當(2,6)(3,6)(5,6)樣品結果。如果你能解釋一下,我有一些想法可以填補缺失的部分。