-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathlecture07-sql-subqueries-sqlite.sql
164 lines (118 loc) · 4.47 KB
/
lecture07-sql-subqueries-sqlite.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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
--------------------------------------------------------------------------------
-- CSE 344 -- Fall 2013
-- Lecture 08: SUBQUERIES IN SQL
--------------------------------------------------------------------------------
-- run these queries in SQL Lite or in SQL Azure
-- for sqllite only:
.headers on
.mode columns
create table Product(pname varchar(30) primary key, price int, cid int);
create table Company(cid int primary key, cname varchar(10), city varchar(10));
insert into Product values ('gizmo', 100, 1);
insert into Product values('powergizmo', 200, 1);
insert into Product values('iStuff', 500, 2);
insert into Product values('gadget', 300, 2);
insert into Product values('powergadget', 400, 2);
insert into Company values(1,'GizmoWorks','San Jose');
insert into Company values(2,'BigCompany','Boston');
insert into Company values(3,'PowerWorks','Seattle');
--------------------------------------------------------------------------------
-- 1. subqueries in Select:
SELECT X.pname, (SELECT Y.city FROM Company Y WHERE Y.cid=X.cid) as City
FROM Product X;
-- same as:
SELECT X.pname, Y.city
FROM Product X, Company Y
WHERE X.cid=Y.cid;
-- Compute the number of products made by each company:
SELECT DISTINCT C.cname, (SELECT count(*) FROM Product P WHERE P.cid=C.cid)
FROM Company C;
SELECT C.cname, count(*)
FROM Company C, Product P
WHERE C.cid=P.cid
GROUP BY C.cname;
-- they are not exactly equivalent! why?
-- are these queries equivalent? Try them out!
SELECT DISTINCT C.cname, (SELECT count(*) FROM Product P WHERE P.cid=C.cid)
FROM Company C;
SELECT C.cname, count(*)
FROM Company C, Product P
WHERE C.cid=P.cid
GROUP BY C.cname;
SELECT C.cname, count(pname)
FROM Company C LEFT OUTER JOIN Product P
ON C.cid=P.cid
GROUP BY C.cname;
--------------------------------------------------------------------------------
-- 2. subqueries in From:
SELECT X.pname FROM (SELECT * FROM Product AS Y WHERE price > 20) as X
WHERE X.price < 500;
--------------------------------------------------------------------------------
-- 3. subqueries in Where
-- Find all companies that make some products with price < 200
SELECT DISTINCT C.cname
FROM Company C
WHERE EXISTS (SELECT * FROM Product P WHERE C.cid = P.cid and P.price < 200);
SELECT DISTINCT C.cname
FROM Company C
WHERE C.cid IN (SELECT P.cid FROM Product P WHERE P.price < 200);
-- Find all companies that make only products with price < 200
-- Step 1. Find the other companies: i.e. s.t. some product >= 200
SELECT DISTINCT C.cname
FROM Company C
WHERE C.cid IN (SELECT P.cid FROM Product P WHERE P.price >= 200);
-- Step 2. Find all companies s.t. all their products have price < 200
SELECT DISTINCT C.cname
FROM Company C
WHERE C.cid NOT IN (SELECT P.cid FROM Product P WHERE P.price >= 200);
-- Altenratively:
-- Step 1 using 'exists':
SELECT DISTINCT C.cname
FROM Company C
WHERE EXISTS (SELECT * FROM Product P WHERE P.cid = C.cid and P.price >= 200);
-- Step 2 using 'not exists':
SELECT DISTINCT C.cname
FROM Company C
WHERE EXISTS (SELECT * FROM Product P WHERE P.cid = C.cid and P.price >= 200);
----------------------------------------------------------------------
-- Unnesting aggregates
-- equivalent queries:
SELECT DISTINCT city, (SELECT count(*) FROM Company Y WHERE X.city = Y.city)
FROM Company X;
SELECT city, count(*)
FROM Company
GROUP BY city;
-- non-equivalent queries (why?)
SELECT DISTINCT X.city, (SELECT count(*) FROM Product Y, Company Z WHERE Z.cid=Y.cid
AND Z.city = X.city)
FROM Company X;
SELECT X.city, count(*)
FROM Company X, Product Y
WHERE X.cid=Y.cid GROUP BY X.city;
-- For each city, find the most expensive product made in that city
-- Finding the maximum price is easy…
SELECT x.city, max(y.price)
FROM Company x, Product y
WHERE x.cid = y.cid
GROUP BY x.city;
SELECT DISTINCT u.city, v.pname, v.price
FROM Company u, Product v,
(SELECT x.city, max(y.price) as maxprice
FROM Company x, Product y
WHERE x.cid = y.cid
GROUP BY x.city) w
WHERE u.cid = v.cid
and u.city = w.city
and v.price=w.maxprice;
-- do we neeed DISTINCT?
-- another, more concise solution:
SELECT u.city, v.pname, v.price
FROM Company u, Product v, Company x, Product y
WHERE u.cid = v.cid and u.city = x.city and x.cid = y.cid
GROUP BY u.city, v.pname, v.price
HAVING v.price = max(y.price);
-- and also
SELECT u.city, v.pname, v.price
FROM Company u, Product v
WHERE u.cid = v.cid
and v.price >= ALL (SELECT y.price FROM Company x, Product y WHERE u.city=x.city and x.cid=y.cid);