(SQLZOO最后一题答案详解)(持续更新)2021-01-20-SQL(SQLZOO Self Join)刷题精华部分-HK

深渊向深渊呼唤

SQLZOO - Self Join

SQLZOO最后一题答案

小目录:(SQLZOO Self Join)

将一个表自连接后再分别外接两个表 将一个表自连接两次,解决调度问题
SQLZOO最后一题详解

正文:

    将一个表自连接后再分别外接两个表

先自连接,然后分别对应自连接的两个表进行外连接,对应连接点是外连接的ON连接条件;

SELECT a.company, a.num, stopa.name, stopb.name
FROM route a JOIN route b ON
  (a.company=b.company && a.num=b.num)
  JOIN stops stopa ON (a.stop=stopa.id)#把stopa外接到a
  JOIN stops stopb ON (b.stop=stopb.id)
WHERE stopa.name='Craiglockhart' && stopb.name='London Road'
    (Important)将一个表自连接两次,解决调度问题
    SQLZOO最后一题详解
    (代码风格需要锻炼,求轻喷)

题目:
Find the routes involving two buses that can go from Craiglockhart to Lochend.
Show the bus no. and company for the first bus,
the name of the stop for the transfer,
and the bus no. and company for the second bus.

AC代码:

SELECT  ta.Anum FirstNum, ta.Acom FirstCom, ta.Bname Transfer, tc.Cnum SecondNum, tc.Ccom SecondCom
FROM

(
SELECT  a.num Anum, a.company Acom, a.stop Astop, b.num Bnum, b.company Bcom, b.stop Bstop, stopb.name Bname
FROM route a JOIN route b ON
  (a.company = b.company && a.num = b.num)
             JOIN stops stopb ON 
  (b.stop=stopb.id)

WHERE (a.stop = (SELECT stops.id 
                   FROM stops 
                  WHERE name = 'Craiglockhart')) 
)AS ta,

(
SELECT  a.num Anum, a.company Acom, a.stop Astop, b.num Bnum, b.company Bcom, b.stop Bstop, c.num Cnum, c.company Ccom, c.stop Cstop
FROM route a JOIN route b ON
  (a.company = b.company && a.num = b.num)
             JOIN route c ON
  (b.company = c.company && b.num = c.num)

WHERE 
      (c.stop = (SELECT stops.id 
                   FROM stops 
                  WHERE name = 'Lochend')) 
       && (a.stop = b.stop)
)AS tc

WHERE ta.Bstop = tc.Bstop
GROUP BY FirstNum, FirstCom, Transfer, SecondNum, SecondCom

AC结果图:
如果你无法AC,请注意你的题目要求是否有变化。
思路:
(1)先看逻辑框图:
分为红过程和蓝过程,黑色部分为核心逻辑,棕色部分为非核心逻辑;
逻辑框图
(2)口述思路:(字多但简单,理清它需要你的耐心)
思路重点是-不要将整个过程分开成两个完整过程考虑,而是先考虑两个部分过程,再将部分合并为整体!

1)(构建框架)将route表自连接两次,形成两个目的地的表和一个中转站的表;

2)(构建框架)将中转站的表在逻辑上拆成两套id(不用拆成两个表分别匹配,否则代码会冗余);
其中的Bstop是用来输出中转站的名字的,这个不是核心逻辑的关键;

3)(id匹配)把整个id匹配过程拆分成两个过程,红过程和蓝过程,分别对应第二趟车和第一趟车;

4)(id匹配)在红过程中,我们固定目的地L的id,会得到一组对应的中转站id,我们称之为红中转站id;在蓝过程中,我们固定目的地C的id,会得到一组对应的中转站id,我们称之为蓝中转站id;
在这一步,实际上我们已经筛选出了第一趟车和第二趟车的id,下面要想办法把他们连接起来;

5)(id匹配)设定条件(红中转站id=蓝中转站id),此时就能将红过程和蓝过程连接起来,成为了完整过程;

本题思考结束,把代码写出来就行了。
欢迎指正!

栏目