我有两个带有用户ID的表,另一个表通过存储两个用户ID来表示两个用户之间的关系。如何计算两个用户之间的相互关系,相互关系定义为两个用户都有关系的用户数。
例如,如果我有:
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);
答案 0 :(得分: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 by
和count()
。
答案 1 :(得分:0)
SELECT user1Id, user2ID, COUNT(*) MutualCount
FROM UserVsUser
GROUP BY user1Id, user2ID
ORDER BY MutualCount DESC
UserVsUser是表示两个用户之间关系的表。
答案 2 :(得分: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;
这应该产生与当前接受的答案类似的结果,但代码更少,执行速度更快。
我从示例数据中了解为什么对(1,3)
的计数为2
,以及对(2,3)
,(1,2)
和{{1}对的原因所有产生(1,5)
。但是,我从示例中无法理解为什么1
,(1,4)
或(1,6)
会在结果中显示,尤其是在(3,4)
,(2,6)
和示例结果中的(3,6)
不。如果你能解释一下,我有一些想法可以填补缺失的部分。