-
Notifications
You must be signed in to change notification settings - Fork 2
/
09.2 Self JOIN.sql
134 lines (99 loc) · 3.58 KB
/
09.2 Self JOIN.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
Self Join
Edinburgh Buses
Details of the database Looking at the data:
stops(id, name)
route(num, company, pos, stop)
*/
/*
#1)
Q. How many stops are in the database.
*/
SELECT COUNT(DISTINCT stop) stops
FROM route;
/*
#2)
Q. Find the id value for the stop 'Craiglockhart'.
*/
SELECT id
FROM stops
WHERE name = 'Craiglockhart';
/*
#3)
Q. Give the id and the name for the stops on the '4' 'LRT' service.
*/
SELECT id, name
FROM stops JOIN route ON stops.id = route.stop
WHERE num = '4';
/*
#4) Routes and stops
The query shown gives the number of routes that visit either London Road (149) or Craiglockhart (53).
Run the query and notice the two services that link these stops have a count of 2.
Q. Add a HAVING clause to restrict the output to these two routes.
*/
SELECT company, num, COUNT(*) visits
FROM route
WHERE (stop = 149) OR (stop = 53)
GROUP BY company, num
HAVING visits = 2;
/*
#5)
Execute the self join shown and observe that b.stop gives all the places you can get to from Craiglockhart, without changing routes.
Change the query so that it shows the services from Craiglockhart to London Road.
Q. Change the query so that it shows the services from Craiglockhart to London Road.
*/
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 = 149;
/*
#6)
The query shown is similar to the previous one,
however by joining two copies of the stops table we can refer to stops by name rather than by number.
Q. Change the query so that the services between 'Craiglockhart' and 'London Road' are shown.
*/
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');
/*
#7) Using a self join
Q. Give a list of all the services which connect stops 115 and 137 ('Haymarket' and 'Leith')
*/
SELECT DISTINCT a.company, a.num
FROM route a JOIN route b ON (a.company = b.company) AND (a.num = b.num)
WHERE (a.stop = 115) AND (b.stop = 137);
/*
#8)
Q. Give a list of the services which connect the stops 'Craiglockhart' and 'Tollcross'
*/
SELECT a.company, a.num
FROM route a INNER JOIN route b ON (a.company = b.company) AND (a.num = b.num)
JOIN stops stopa ON (stopa.id = a.stop)
JOIN stops stopb ON (stopb.id = b.stop)
WHERE (stopa.name = 'Craiglockhart') AND (stopb.name = 'Tollcross');
/*
#9)
Q. Give a distinct list of the stops which may be reached from 'Craiglockhart' by taking one bus,
including 'Craiglockhart' itself, offered by the LRT company.
Include the company and bus no. of the relevant services.
*/
SELECT stopb.name, b.company, b.num
FROM route a JOIN route b ON (a.company = b.company) AND (a.num = b.num)
JOIN stops stopa ON stopa.id = a.stop
JOIN stops stopb ON stopb.id = b.stop
WHERE stopa.name = 'Craiglockhart';
/*
#10)
Q. 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.
*/
SELECT r1.num, r1.company, s1.name, r4.num, r4.company
FROM route r1 JOIN route r2 ON (r1.num = r2.num) AND (r1.company = r2.company)
JOIN stops s1 ON r2.stop = s1.id
JOIN route r3 ON s1.id = r3.stop
JOIN route r4 ON (r3.num = r4.num) AND (r3.company = r4.company)
WHERE (r1.stop = (SELECT id FROM stops WHERE name = 'Craiglockhart')) AND
(r4.stop = (SELECT id FROM stops WHERE name = 'Lochend'))
ORDER BY r1.num, s1.name, r4.num;