sqlzoo 9.Self join 答案

有什么问题,欢迎评论或私聊。转载请私聊博主,谢谢。

原题链接:https://sqlzoo.net/wiki/Self_join

其他题解连接:https://blog.csdn.net/aiqiyizz/article/details/109057732

9 Self join

9.1 Summary

SELECT COUNT(*)
FROM stops

9.2

SELECT id
FROM stops
WHERE name = 'Craiglockhart'

9.3

我收回题意清晰的说法(没说过)。这题意(英文):Give the id and the name for the stops on the ‘4’ ‘LRT’ service. 问题太多了。

  1. ‘4’ ‘LRT’ service是什么???是route的num和company

    能理解后,就能打出下面这种,步骤:找出对应stopid ⇒ \Rightarrow 输出对应id和name

    SELECT id, name
    FROM stops
    WHERE id IN
    (
      SELECT stop
      FROM route
      WHERE num = 4 AND company = 'LRT'
    )

    然后会发现Wrong Answer了,看了下数据发现一种诡异的排序方式。

  2. 原因是需要按照route的pos进行排序。被迫使用JOIN。以下正解

    SELECT stops.id, stops.name
    FROM route INNER JOIN stops ON route.stop = stops.id
    WHERE route.num = 4 AND route.company = 'LRT'
    ORDER BY route.pos

9.4 Routes and stops

SELECT company, num, COUNT(*)
FROM route WHERE stop=149 OR stop=53
GROUP BY company, num
HAVING COUNT(*) = 2

9.5

题意又长又臭。例子已给all the places you can get to from Craiglockhart,你需要from Craiglockhart to London Road

也就是to的地点id为London Road的id即可。

SELECT a.company, a.num, a.stop, b.stop
FROM route a JOIN route b ON
  (a.company=b.company AND a.num=b.num)
WHERE a.stop=53 
  AND b.stop=(SELECT id FROM stops WHERE name = 'London Road')

9.6

唯一有用的一句话:Change the query so that the services between ‘Craiglockhart’ and ‘London Road’ are shown.

程序没看懂直接加就correct了。

SELECT a.company, a.num, stopa.name, stopb.name
FROM route a JOIN route b ON
  (a.company=b.company AND a.num=b.num)
  JOIN stops stopa ON (a.stop=stopa.id)
  JOIN stops stopb ON (b.stop=stopb.id)
WHERE stopa.name='Craiglockhart' AND stopb.name = 'London Road'

9.7 Using a self join

SELECT DISTINCT temp1.company, temp1.num
FROM route temp1,
     route temp2
WHERE temp1.stop = 115
  AND temp2.stop = 137
  AND temp1.num = temp2.num

9.8

添加查id部分

SELECT DISTINCT temp1.company, temp1.num
FROM route temp1,
     route temp2
WHERE temp1.stop = (SELECT id FROM stops WHERE name = 'Craiglockhart')
  AND temp2.stop = (SELECT id FROM stops WHERE name = 'Tollcross')
  AND temp1.num = temp2.num

9.9

有点麻烦,重构了一遍才过。

题目格式要求:stops.name,route.company,route.num

获取Craiglockhart车站的id ⇒ \Rightarrow 通过id获取经过Craiglockhart车站的路线 ⇒ \Rightarrow 找出在所需路线的城市,限制公司

-- 找出在所需路线的城市,限制公司
SELECT
  stops.name,
  route.company,
  route.num
FROM
  stops INNER JOIN route ON stops.id = route.stop
WHERE num IN 
(
  -- 通过id获取经过Craiglockhart车站的路线
  SELECT
    num
  FROM
    route
  WHERE
    stop = (
      -- 获取Craiglockhart车站的id
      SELECT id
      FROM stops
      WHERE name = 'Craiglockhart'
    )
)
AND company = 'LRT'

9.10

最难一题,没有之一。值得一位sql新手来写一篇题解。

题意:求出Craiglockhart做两次公交车到达Lochend的路线。

输出要求:(第一次公交车编号,第一次公交车公司,中转站名称,第二次公交车编号,第二次公交车公司)

隐含要求:ORDER BY 第一次公交车编号, 中转站名称, 第二次公交车编号

题解:

首先要找出一轮公交车能到的车站和路线,这在上一题就做过了,这并不难。如下

SELECT
  tempr2.num, tempr2.company, tempr2.stop
FROM
  route tempr1
  JOIN route tempr2 ON (
    tempr1.num = tempr2.num
    AND tempr1.company = tempr2.company
  )
WHERE
  tempr1.stop = (
    SELECT
      id
    FROM
      stops
    WHERE
      name = 'Craiglockhart'
  )

麻烦的是要将两轮公交车的联系起来。

表格从上往下创建并连接成答案。

名称 作用
tempr1 Craiglockhart能前往的车站
tempr2 第一轮公交车能前往的车站以及经过的路线
stop 提取出一轮公交车前往车站的名字
tempr3 在第一轮公交车前往的车站出发,能前往的第二轮公交车路线
tempr4 第二轮公交车能前往的车站以及到达Lochend经过的路线

如无法理解下面部分前后逻辑关系,可先看9.9部分

只看tempr1和tempr2部分,会发现tempr2是Craiglockhart能前往的城市;

只看tempr3和tempr4部分,会发现tempr4是能到达Lochend的城市;

tempr2和tempr3的部分,tempr3是从tempr2的城市出发能前往的城市。

限制tempr1为Craiglockhart出发的方法是给tempr1.stop添加where限制;限制tempr4为到达Lochend的方法是给tempr4.stop添加where限制。

代码部分,因为进行整合过,不是很容易理解。如果把每个部分的数据拆分出来,会容易理解些。

SELECT
  tempr2.num num1,
  tempr2.company,
  stops.name,
  tempr4.num num2,
  tempr4.company
FROM
  -- tempr1:Craiglockhart能前往的路线
  route tempr1
  -- tempr2:找出一次车的车站能抵达的车站
  JOIN route tempr2 ON (
      tempr1.num = tempr2.num
      AND tempr1.company = tempr2.company
  )
  JOIN stops ON stops.id = tempr2.stop
  -- tempr3:找出再坐一次车的车站能抵达的路线
  JOIN route tempr3 ON tempr2.stop = tempr3.stop
  -- tempr4:找出能抵达Lochend的车站
  JOIN route tempr4 ON (
    tempr4.num = tempr3.num
    AND tempr4.company = tempr3.company
  )
WHERE
  -- Craiglockhart出发限制
  tempr1.stop = (
    SELECT
      id
    FROM
      stops
    WHERE
      name = 'Craiglockhart'
  )
  AND
  -- 到达Lochend限制
  tempr4.stop = (
    SELECT
      id
    FROM
      stops
    WHERE
      name = 'Lochend'
  )
ORDER BY
  num1, name, num2

猜你喜欢

转载自blog.csdn.net/aiqiyizz/article/details/109064583