[英]sql self-join and subquery questions - stanford sql course
我一直在认真思考这个问题,我认为代码的问题可能是由于最后一部分。 我认为我需要使用不存在或不存在的子查询来解决问题,但无法弄清楚如何解决该问题。 谢谢!
问题:
对于每个喜欢两个都不是朋友的学生B的学生A,找出他们是否有一个共同的朋友C(谁可以介绍他们!)。 对于所有这些三重奏,返回名称A,B和C。
我的代码:
select h1.name, h1.grade, h2.name, h2.grade, h3.name, h3.grade
from highschooler h1,
highschooler h2,
highschooler h3,
likes,
friend f1,
friend f2
where h1.id = likes.id1
and h2.id = likes.id2
and h3.id = f1.id2
and h2.id = f2.id1
and h3.id = f2.id2
and h1.id = f1.id1
and h2.id <> f1.id2
表:高中生
ID name grade
1510 Jordan 9
1689 Gabriel 9
1381 Tiffany 9
1709 Cassandra 9
1101 Haley 10
1782 Andrew 10
1468 Kris 10
1641 Brittany 10
1247 Alexis 11
1316 Austin 11
1911 Gabriel 11
1501 Jessica 11
1304 Jordan 12
1025 John 12
1934 Kyle 12
1661 Logan 12
友人
ID1 ID2
1510 1381
1510 1689
1689 1709
1381 1247
1709 1247
1689 1782
1782 1468
1782 1316
1782 1304
1468 1101
1468 1641
1101 1641
1247 1911
1247 1501
1911 1501
1501 1934
1316 1934
1934 1304
1304 1661
1661 1025
1381 1510
1689 1510
1709 1689
1247 1381
1247 1709
1782 1689
1468 1782
1316 1782
1304 1782
1101 1468
1641 1468
1641 1101
1911 1247
1501 1247
1501 1911
1934 1501
1934 1316
1304 1934
1661 1304
1025 1661
喜欢
ID1 ID2
1689 1709
1709 1689
1782 1709
1911 1247
1247 1468
1641 1468
1316 1304
1501 1934
1934 1501
1025 1101
它出来的结果比预期的要复杂一些,但似乎可行
select * into #likes
from(
select '1689'ID1,'1709'ID2 union
select '1709','1689' union
select '1782','1709' union
select '1911','1247' union
select '1247','1468' union
select '1641','1468' union
select '1316','1304' union
select '1501','1934' union
select '1934','1501' union
select '1025','1101')x
select * into #Highschooler
from (
select '1510'ID,'Jordan'name, 9 grade union
select '1689','Gabriel', 9 union
select '1381','Tiffany', 9 union
select '1709','Cassandra', 9 union
select '1101','Haley', 10 union
select '1782','Andrew', 10 union
select '1468','Kris', 10 union
select '1641','Brittany', 10 union
select '1247','Alexis', 11 union
select '1316','Austin', 11 union
select '1911','Gabriel', 11 union
select '1501','Jessica', 11 union
select '1304','Jordan', 12 union
select '1025','John', 12 union
select '1934','Kyle', 12 union
select '1661','Logan', 12 ) x
select * into #Friend
from(
select '1510'ID1,'1381'ID2 union
select '1510','1689' union
select '1689','1709' union
select '1381','1247' union
select '1709','1247' union
select '1689','1782' union
select '1782','1468' union
select '1782','1316' union
select '1782','1304' union
select '1468','1101' union
select '1468','1641' union
select '1101','1641' union
select '1247','1911' union
select '1247','1501' union
select '1911','1501' union
select '1501','1934' union
select '1316','1934' union
select '1934','1304' union
select '1304','1661' union
select '1661','1025' union
select '1381','1510' union
select '1689','1510' union
select '1709','1689' union
select '1247','1381' union
select '1247','1709' union
select '1782','1689' union
select '1468','1782' union
select '1316','1782' union
select '1304','1782' union
select '1101','1468' union
select '1641','1468' union
select '1641','1101' union
select '1911','1247' union
select '1501','1247' union
select '1501','1911' union
select '1934','1501' union
select '1934','1316' union
select '1304','1934' union
select '1661','1304' union
select '1025','1661' ) x
select
x.ID1 'A'
,x.ID2 'B'
, case when y.ID1 = z.ID1 then z.ID1
when y.ID2 = z.ID2 then z.ID2
when y.ID1 = z.ID2 then z.ID2
when y.ID2 = z.ID1 then z.ID1 end as 'C'
into #result
from
(
select l.ID1,l.ID2
from #likes l
left join #Friend f
on l.ID1 = f.ID1
and l.ID2 = f.ID2
where f.ID1 is null ) x
join (
select x.*, y.ID1 lid1 from #Friend x
join (
select l.ID1
from #likes l
left join #Friend f
on l.ID1 = f.ID1
and l.ID2 = f.ID2
where f.ID1 is null
union all
select l.ID2
from #likes l
left join #Friend f
on l.ID1 = f.ID1
and l.ID2 = f.ID2
where f.ID1 is null
)y
on x.ID1 = y.ID1) y
on x.ID1 = y.lid1
join (
select x.*,y.ID1 lid2 from #Friend x
join
(
select l.ID1
from #likes l
left join #Friend f
on l.ID1 = f.ID1
and l.ID2 = f.ID2
where f.ID1 is null
union all
select l.ID2
from #likes l
left join #Friend f
on l.ID1 = f.ID1
and l.ID2 = f.ID2
where f.ID1 is null
)y
on x.ID2 = y.ID1) z
on x.ID2 = z.lid2
where y.ID1 = z.ID1 or y.ID2 = z.ID2 or y.ID1 = z.ID2 or y.ID2 = z.ID1
select
h1.*
,h2.*
,H3.*
from #result r
join #Highschooler h1
on r.A = h1.ID
join #Highschooler h2
on r.b = h2.ID
join #Highschooler h3
on r.c = h3.ID
您也可以尝试以下查询:
select * into #likes
from(
select '1689'ID1,'1709'ID2 union
select '1709','1689' union
select '1782','1709' union
select '1911','1247' union
select '1247','1468' union
select '1641','1468' union
select '1316','1304' union
select '1501','1934' union
select '1934','1501' union
select '1025','1101')x
select * into #Highschooler
from (
select '1510'ID,'Jordan'name, 9 grade union
select '1689','Gabriel', 9 union
select '1381','Tiffany', 9 union
select '1709','Cassandra', 9 union
select '1101','Haley', 10 union
select '1782','Andrew', 10 union
select '1468','Kris', 10 union
select '1641','Brittany', 10 union
select '1247','Alexis', 11 union
select '1316','Austin', 11 union
select '1911','Gabriel', 11 union
select '1501','Jessica', 11 union
select '1304','Jordan', 12 union
select '1025','John', 12 union
select '1934','Kyle', 12 union
select '1661','Logan', 12 ) x
select * into #Friend
from(
select '1510'ID1,'1381'ID2 union
select '1510','1689' union
select '1689','1709' union
select '1381','1247' union
select '1709','1247' union
select '1689','1782' union
select '1782','1468' union
select '1782','1316' union
select '1782','1304' union
select '1468','1101' union
select '1468','1641' union
select '1101','1641' union
select '1247','1911' union
select '1247','1501' union
select '1911','1501' union
select '1501','1934' union
select '1316','1934' union
select '1934','1304' union
select '1304','1661' union
select '1661','1025' union
select '1381','1510' union
select '1689','1510' union
select '1709','1689' union
select '1247','1381' union
select '1247','1709' union
select '1782','1689' union
select '1468','1782' union
select '1316','1782' union
select '1304','1782' union
select '1101','1468' union
select '1641','1468' union
select '1641','1101' union
select '1911','1247' union
select '1501','1247' union
select '1501','1911' union
select '1934','1501' union
select '1934','1316' union
select '1304','1934' union
select '1661','1304' union
select '1025','1661' ) x
--Select list of Likes which are not friends of each other
SELECT * INTO #IntermediateResults FROM #Likes l
WHERE NOT EXISTS (SELECT 1 FROM #Friend WHERE ID1 = l.ID1 AND ID2 = l.ID2)
--Select a distinct list of friends for each person in the above table.
SELECT DISTINCT Person,Friend INTO #PersonFriend FROM
(
SELECT F.ID1 AS Person, F.ID2 AS Friend
FROM #Friend F
JOIN #IntermediateResults IR ON F.ID1 IN (IR.ID1 , IR.ID2)
UNION ALL
SELECT F.ID1 AS Person, F.ID2 AS Friend
FROM #Friend F
JOIN #IntermediateResults IR ON F.ID2 IN (IR.ID1 , IR.ID2)
)aa
--Select those records where a friend of one person is the friend of another person as well.
SELECT
HS1.ID AS Person1ID,
HS1.Name AS Person1Name,
HS1.grade AS Person1Grade,
HS2.ID AS Person2ID,
HS2.Name AS Person2Name,
HS2.grade AS Person2Grade,
HS3.ID AS CommonFriendID,
HS3.Name AS CommonFriendName,
HS3.grade AS CommonFriendGrade
FROM
#IntermediateResults IR
JOIN #PersonFriend PersonFriend ON IR.ID1 = PersonFriend.Person
JOIN #Highschooler HS1 ON IR.ID1 = HS1.ID
JOIN #Highschooler HS2 ON IR.ID2 = HS2.ID
JOIN #Highschooler HS3 ON PersonFriend.Friend = HS3.ID
WHERE
EXISTS (SELECT 1 FROM #IntermediateResults IR2
JOIN #PersonFriend PersonFriend1 ON IR2.ID2 = PersonFriend1.Person
WHERE ID2 = IR.ID2 AND PersonFriend1.Friend = PersonFriend.Friend)
select h1.name, h1.grade, h2.name, h2.grade, h3.name, h3.grade
from highschooler h1,
highschooler h2,
highschooler h3,
likes,
friend f1,
friend f2
where h1.id = likes.id1
and h2.id = likes.id2
and not exists (select * from Friend F where F.ID1 = H1.ID and F.ID2 = H2.ID)
and h3.id = f1.id2
and h2.id = f2.id1
and h3.id = f2.id2
and h1.id = f1.id1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.