(SQLZOO最後一題答案詳解)(持續更新)2021-01-20-SQL(SQLZOO Self Join)刷題精華部分-HK

SQLZOO - Self Join

SQLZOO最後一題答案

小目錄:(SQLZOO Self Join)

  • 將一個表自連接後再分別外接兩個表
  • 將一個表自連接兩次,解決調度問題
    SQLZOO最後一題詳解

正文:

  1. 將一個表自連接後再分別外接兩個表

先自連接,然後分別對應自連接的兩個表進行外連接,對應連接點是外連接的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'
  1. (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),此時就能將紅過程和藍過程連接起來,成爲了完整過程;

本題思考結束,把代碼寫出來就行了。
歡迎指正!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章