在连接较少的关系中找到三个对象

时间:2015-09-05 23:11:30

标签: sql sqlite

我正在做一个SQL练习并确定了一个解决方案,但我觉得在我的解决方案中加入4个表是蛮力的方式来做我所做的。

我有以下表格:

Highschooler ( ID, name, grade )

Friend ( ID1, ID2 ) ID1是ID2 =>的共同朋友。如果[ID1, ID2]中存在Friend,则必须[ID2, ID1]

Likes ( ID1, ID2 ) ID1被ID2吸引

问题是:

  

对于每个学生A喜欢学生B,其中两个不是朋友,找出他们是否有共同的朋友C(谁可以介绍他们!)。对于所有此类三人组,请返回A,B和C的名称和等级。

我的解决方案:

Select  H1.name, H1.grade, H2.name, H2.grade, H3.name, H3.grade
FROM    Highschooler H1, Highschooler H2, Highschooler H3,

        -- Following table contains each trio of A, B, C
        (Select L.ID1 as ID1, L.ID2 as ID2, F.ID2 as ID3
        FROM (SELECT * FROM Likes EXCEPT SELECT * FROM Friend) as L, Friend as F
        WHERE   L.ID1 = F.ID1 AND -- Found a potential friend C of A
                F.ID2 in (SELECT ID2 FROM Friend WHERE Friend.ID1 = L.ID2)) -- Does potential C appear in list of B's friends?

WHERE   H1.ID = ID1 and H2.ID = ID2 and H3.ID = ID3

我觉得Highschooler H1, Highschooler H2, Highschooler H3声明是我的强奸'。

第一个SELECT中的FROM语句正确找到了[A.ID, B.ID, C.ID]三人组,而语句的其余部分只提取了响应这些ID的名称和等级。

有没有比我做过的4-way join更好的方法呢?

1 个答案:

答案 0 :(得分:2)

此查询应该给出相同的结果,但使用稍微不同的语法。最后,你需要加入Highschooler三次,因为你需要三个不同的人的名字和等级 - 这并没有多大关系。

select 
    liker.name, liker.grade, 
    liked.name, liked.grade, 
    common_friend.name, common_friend.grade
from likes l 

-- student1 who likes
join Highschooler liker on liker.ID = l.ID1 

-- student2 who is liked
join Highschooler liked on liked.ID = l.ID2 

-- friends on student1
join Friend f on l.ID1 = f.ID1 
            -- that are in student2s friends
             and f.ID2 in (select id1 from friend where id2 = l.ID2) 
-- the common friend
join Highschooler common_friend on common_friend.ID = f.ID2 

-- student1 and student2 can't be friends
where not exists (select 1 from Friend where ID1 = l.ID1 and id2 = l.ID2)