sql自加入和子查询问题 - stanford sql课程

时间:2016-04-07 23:42:59

标签: sql subquery self-join

我一直在努力思考这个问题,我认为我的代码问题可能是由于最后一部分。我想我需要使用不存在或不存在的子查询来解决问题,但无法弄清楚如何解决问题。谢谢!

问题:

对于每个学生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, 
     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

表: Highschooler

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

3 个答案:

答案 0 :(得分:0)

它的出现比预期的要复杂一点,但似乎有效。

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 

答案 1 :(得分:0)

您也可以尝试以下查询:

table

答案 2 :(得分:0)

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