想象一下,我们有两个表如下:
朋友(uid1 int,uid2 int)
这个表格包含了彼此之友的所有人的身份。
喜欢(uid,lid)
此表保存每个用户ID所喜欢的项目(按方式索引)
我想知道,对于每个朋友A和B,他们喜欢的项目数量与他们喜欢的多少独特项目的组合方式。
我正在使用MySQL,因此我们没有完全加入。
这对我来说似乎是一个如此复杂的问题。我想我得到一些点来获得这些价值观,但我想知道别人会怎么做:
以下是为朋友和喜欢
构建示例表的代码create table friend (uid1 int, uid2 int);
insert into friend values
(1,2),
(2,1),
(1,3),
(2,3);
create table likes(uid int, lid int);
insert into likes values
(1, 2),
(1, 3),
(1, 4),
(2, 1),
(2, 2),
(3, 5),
(3, 4);
这是我到目前为止的实现:
select r.uid1, r.uid2,
sum(case when r.lid1 is null then 0 else 1 end) as uniqueLike1,
sum(case when r.lid2 is null then 0 else 1 end) as uniqueLike2,
sum(case when r.lid1 is not null and r.lid2 is not null then 1 else 0 end) as uniqueLike1and2
from
(select f.uid1 as uid1, f.uid2 as uid2, l1.lid as lid1, l2.lid as lid2
from friend f join likes l1 on f.uid1 = l1.uid left join likes l2 on f.uid2=l2.uid and l1.lid = l2.lid
union
select ff.uid1 as uid1, ff.uid2 as uid2, ll2.lid as lid1, ll1.lid as lid2
from friend ff join likes ll1 on ff.uid2 = ll1.uid left join likes ll2 on ff.uid1=ll2.uid and ll1.lid = ll2.lid) r
group by r.uid1, r.uid2;
答案 0 :(得分:0)
这不是传统方法。我甚至不承诺它是有效的(特别是如果用户喜欢很多东西)。但是,它具有相对简单的优点:
select f.uid1, f.uid2,
count(distinct case when l1.lid = l2.lid then l1.lid end) as likes_in_common,
(count(distinct l1.lid) -
count(distinct case when l1.lid = l2.lid then l1.lid end)
) as likes_only1,
(count(distinct l2.lid) -
count(distinct case when l1.lid = l2.lid then l1.lid end)
) as likes_only2
from friend f left join
likes l1
on l1.uid = f.uid1 left join
likes l2
on l2.uid = f.uid2
group by f.uid1, f.uid2;
这个想法是计算共同的项目数量。这是第一个count()
表达式。然后,通过减法给出唯一的。
COUNT(DISTINCT)
是必需的,因为FROM
子句会为两个用户的所有相似内容生成笛卡尔积。