我正在做一个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更好的方法呢?
答案 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)