2015-10-16 127 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)样品结果。如果你能解释一下,我有一些想法可以填补缺失的部分。