繁体   English   中英

SQL自联接和子查询问题-斯坦福SQL课程

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM