MYSQL:在朋友中找到类似和独特的喜欢

时间:2016-11-21 00:54:19

标签: mysql sql join

想象一下,我们有两个表如下:

  1. 朋友(uid1 int,uid2 int)

    这个表格包含了彼此之友的所有人的身份。

  2. 喜欢(uid,lid)

    此表保存每个用户ID所喜欢的项目(按方式索引)

  3. 我想知道,对于每个朋友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;
    

1 个答案:

答案 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子句会为两个用户的所有相似内容生成笛卡尔积。