sql 2 – the sequelcs186/sp08/notes/20-sql2.pdf•the where clause can itself contain an sql query!...
TRANSCRIPT
CS 186, Spring 2007, Lecture 8R&G, Chapter 5
Mary Roth
∀
∃
The important thing is not tostop questioning.
Albert Einstein
Life is just a bowl of queries.
-Anon(not Forrest Gump)
SQL 2 – The Sequel
Review: SQL DML
• DML includes 4 main statements:SELECT (query), INSERT, UPDATE and DELETE
• e.g: SELECT S.name, E.cidFROM Students S, Enrolled EWHERE S.sid = E.sid AND
S.age=19 SELECT
PROJECT
JOIN
SELECT R.sidFROM Boats B,Reserves RWHERE B.color = ‘red’
AND R.bid=B.bid
INTERSECT
SELECT R.sidFROM Boats B,Reserves RWHERE B.color = ‘green’ ANDR.bid=B.bid Reserves
9/131032
9/131051
9/121011
daybidsid
redSanta Maria103
greenTitanic105
bluePinta102
redNina101
colorbnamebid
Boats
2
1
sid
1
sid∩ = 1
sid
Now let’s do this witha self-join
Example: Find sailors who have reserved a redand a green boat
SELECT R1.sidFROM Boats B1, Reserves R1, Boats B2, Reserves R2
WHERE B1.color = ‘red’ AND B1.bid=R1.bid
AND B2.color = ‘green’ AND B2.bid=R2.bid
AND R1.sid=R2.sid
Find sids of sailors who’ve reserved a red and a greenboat
9/131032
9/131051
9/121011
daybidsid
redSanta Maria103
greenTitanic105
bluePinta102
redNina101
colorbnamebid
Find red reserved boats
Find green reserved boats
Find matching green and redreserved boats
2
1
sid
1
sid
= 1
sid
• The WHERE clause can itself contain an SQL query!(Actually, so can FROM and HAVING clauses can too)
Nested Queries
SELECT S.snameFROM Sailors SWHERE S.sid IN (SELECT R.sid FROM Reserves R
WHERE R.bid=103)
e.g. Find the names of sailors who’ve reserved boat #103:
…and then check each the sid ofeach tuple in Sailors to see if it isin S1
First compute the set of all sailors that havereserved boat 103…
9/131032
9/131051
9/121011
daybidsid
278Sam3
392Bilbo2
227Frodo1
ageratingsnamesid
Sailors
Reserves
S
2
sid
S
S
Bilbo
sname
• This nested query was uncorrelated because the subquerydoes not refer to anything in the enclosing query
Nested Queries
SELECT S.snameFROM Sailors SWHERE S.sid IN (SELECT R.sid FROM Reserves R
WHERE R.bid=103)
It can evaluated once and then checked foreach tuple in enclosing query
• Nested queries can also be correlated; the subqueryrefers to the enclosing query
Nested Queries with correlation
The subquery must be re-evaluated for each tuple inenclosing query
SELECT S.snameFROM Sailors SWHERE EXISTS (SELECT * FROM Reserves R WHERE R.bid=103 AND R.sid=S.sid)
EXISTS is a set operator that is true if result of setexpression has at least one tuple
Nested Queries
e.g. Find the names of sailors who’ve reserved boat #103:
9/131032
9/131051
9/121011
daybidsid
278Sam3
392Bilbo2
227Frodo1
ageratingsnamesid
SailorsReserves
S
S
S
SELECT S.snameFROM Sailors SWHERE EXISTS (SELECT * FROM Reserves R WHERE R.bid=103 AND R.sid=S.sid)
daybidsid
Notice that this querycomputes the sameanswer as the previousquery!
321
2 103 9/13
Set-Comparison Operators
• <tuple expression> IN <set expression>– True if <tuple> is a member of <set>– Also, NOT IN
• EXISTS <set expression>– True if <set expression> evaluates to a set with at least one member– Also, NOT EXISTS
• UNIQUE <set expression>– True if <set expression> evaluates to a set with no duplicates; each
row can appear exactly once– Also, NOT UNIQUE
• <tuple expression> comparison op ANY <set expression>– True if <set expression> contains at least one member that makes the
comparison true– Also, op ALL
Use NOT Exists for Division
SELECT S.snameFROM Sailors SWHERE NOT EXISTS (SELECT B.bid FROM Boats B WHERE NOT EXISTS (SELECT R.bid FROM Reserves R WHERE R.bid=B.bid AND R.sid=S.sid))
Find Sailors S such that ...
there is no boat B...
without a reservation bySailor S
Find sailors who’ve reserved all boats.X = set of sailors and Y = set of all boats with reservations.
Recall: X/Y means only give me X tuples that have a match in Y.
2
Division
9/141033
9/121013
9/131032
9/131031
9/121031
daybidsid
278Sam3
392Bilbo2
227Frodo1
ageratingsnamesid
Sailors
Reserves
S
S
S
SELECT S.snameFROM Sailors SWHERE NOT EXISTS (SELECT B.bid FROM Boats B WHERE NOT EXISTS (SELECT R.bid FROM Reserves R WHERE R.bid=B.bid AND R.sid=S.sid))
bluePinta103
redNina101
colorbnamebid
Boats
1101
R
RR
B
B
3103
RR
UNIQUE
9/131032
9/131031
9/121031
daybidsid
278Sam3
392Bilbo2
227Frodo1
ageratingsnamesid
SailorsReserves
S
S
S
daybidsid
2 103 9/13
Find the names of sailors who’ve reserved boat #103exactly once
SELECT S.snameFROM Sailors SWHERE UNIQUE (SELECT sid, bid FROM Reserves R WHERE R.bid=103 AND S.sid=R.sid) 321
ANY
SELECT *FROM Sailors SWHERE S.rating > ANY(SELECT S2.rating FROM Sailors S2 WHERE S2.sname=‘Bilbo’)
Find sailors whose rating is greater than that of some sailorcalled Bilbo:
278Sam3
392Bilbo2
227Frodo1
ageratingsnamesid
S1
278Sam3
392Bilbo2
227Frodo1
ageratingsnamesid
S2
392Bilbo2
ageratingsnamesid
Correlated oruncorrelated?
Uncorrelated!
Intermission
Aggregate Operators• Very powerful; enables computations over sets of tuples
SELECT AVG (S.age)FROM Sailors SWHERE S.rating=10
SELECT COUNT (*)FROM Sailors S
• COUNT: returns a count of tuples inthe set
• AVG: returns average of columnvalues in the set
• SUM: returns sum of column values inthe set
• MIN, MAX: returns min (max) value ofcolumn values in a set.
• DISTINCT can be added to COUNT,AVG, SUM to perform computationonly over distinct values.
SELECT AVG(DISTINCT S.age)FROM Sailors SWHERE S.rating=10
Find name and age of the oldest sailor(s)
SELECT S.sname, MAX (S.age)FROM Sailors S
Aggregate Operators
What will the result be? 278Sam3
392Bilbo2
227Frodo1
ageratingsnamesid
Sailors
39Sam
39Bilbo
39Frodo
agesname
XNot legal syntax; no other columnsallowed in SELECT clause without aGROUP BY clause(we’ll learn about those next)
Find name and age of the oldest sailor(s)
SELECT S.sname, S.ageFROM Sailors SWHERE S.age = (SELECT MAX (S2.age) FROM Sailors S2)
Aggregate Operators
Instead:
Find the maximum age…
And then find thesailors(s) of that age…
GROUP BY and HAVING
• So far, we’ve seen aggregate operators applied to alltuples.– What if we want to apply ops to each of several groups of tuples?
• Consider: Find the age of the youngest sailor for eachrating level.– In general, we don’t know how many rating levels exist, and what
the rating values for these levels are!– Suppose we know that rating values go from 1 to 10; we can
write 10 queries that look like this (!):
SELECT MIN (S.age)FROM Sailors SWHERE S.rating = i
For i = 1, 2, ... , 10:
Queries With GROUP BY
target-list contains:• list of column names from grouping–list• terms with aggregate operations (e.g., MIN (S.age)).
SELECT [DISTINCT] target-listFROM relation-list[WHERE qualification]GROUP BY grouping-list
• To generate values for a column based on groups ofrows, use aggregate functions in SELECT statements withthe GROUP BY clause
First select these rows…
Then group them by the valuesin these columns…
And finally compute aggregatefunction over each group…
Returning 1 row per group
Group By Example
For each rating, find the age of the youngestsailor with age ≥ 18
SELECT S.rating, MIN (S.age)FROM Sailors SWHERE S.age >= 18GROUP BY S.rating
278Sam3
212Pippin4
178Merry5
392Bilbo2
227Frodo1
ageratingsnamesid
Sailors
227Frodo1Group 1
212Pippin4
392Bilbo2Group 2
278Sam3Group 3
212
278
227
Find the number of reservations for eachred boat.
SELECT B.bid, COUNT(*) AS tot_resFROM Boats B, Reserves RWHERE R.bid=B.bid AND B.color=‘red’GROUP BY B.bid
9/141013
9/131032
9/141014
9/121021
daybidsid
Reserves
redSanta Maria103
bluePinta102
redNina101
colorbnamebid
Boats
9/141013
9/141014
9/131032
1103
2101
Queries With GROUP BY and HAVING
• Use the HAVING clause with the GROUP BY clause to restrictwhich group-rows are returned in the result set
SELECT [DISTINCT] target-listFROM relation-listWHERE qualificationGROUP BY grouping-listHAVING group-qualification
Find the age of the youngest sailor with age ≥18, for each rating with at least 2 such sailors
SELECT S.rating, MIN (S.age)FROM Sailors SWHERE S.age >= 18GROUP BY S.ratingHAVING COUNT (*) > 1
Answer
2 3
Sailors who have reservedall boats
278Sam3
392Bilbo2
227Frodo1
ageratingsnamesid
Sailors
9/101021
9/121022
9/141012
9/131032
9/121021
daybidsid
Reserves
redSanta Maria103
bluePinta102
redNina101
colorbnamebid
Boats
SELECT S.nameFROM Sailors S, reserves RWHERE S.sid = R.sidGROUP BY S.name, S.sidHAVING COUNT(DISTINCT R.bid) = ( Select COUNT (*) FROMBoats)
3
count1021Frodo
Bilbo
Bilbo
Bilbo
Frodo
sname
1012
1022
1032
1021
bidsid
Bilbo
Frodo
sname
101, 102, 1032
102,1021
bidsid
Bilbo
Frodo
sname
32
11
countsid
More about Joins
Explicit join semantics needed unless it is an INNER join(INNER is default)
SELECT (column_list)FROM table_name [INNER | {LEFT |RIGHT | FULL } OUTER] JOIN table_name ON qualification_listWHERE …
Default semantics: Inner Join
Only rows that match search conditions are returned.
SELECT s.sid, s.name, r.bidFROM Sailors s INNER JOIN Reserves rON s.sid = r.sid
Returns only those sailors who have reserved boats
SQL-92 also allows:SELECT s.sid, s.name, r.bidFROM Sailors s NATURAL JOIN Reserves r
“NATURAL” means equi-join for each pair of attributeswith the same name
SELECT s.sid, s.name, r.bidFROM Sailors s INNER JOIN Reserves rON s.sid = r.sid
s.sid s.name r.bid
22 Dustin 101
95 Bob 103
Left Outer Join
Left Outer Join returns all matched rows,plus all unmatched rows from the table on theleft of the join clause
(use nulls in fields of non-matching tuples)
SELECT s.sid, s.name, r.bidFROM Sailors s LEFT OUTER JOIN Reserves rON s.sid = r.sid
Returns all sailors & information on whether theyhave reserved boats
SELECT s.sid, s.name, r.bidFROM Sailors s LEFT OUTER JOIN Reserves rON s.sid = r.sid
s.sid s.name r.bid
22 Dustin 101
95 Bob 103
31 Lubber
Right Outer Join
Right Outer Join returns all matched rows, plusall unmatched rows from the table on the rightof the join clause
SELECT r.sid, b.bid, b.nameFROM Reserves r RIGHT OUTER JOIN Boats bON r.bid = b.bid
Returns all boats & information on which onesare reserved.
SELECT r.sid, b.bid, b.nameFROM Reserves r RIGHT OUTER JOIN Boats bON r.bid = b.bid
r.sid b.bid b.name
22 101 Interlake
102 Interlake
95 103 Clipper
104 Marine
Full Outer Join
Full Outer Join returns all (matched orunmatched) rows from the tables on bothsides of the join clause
SELECT r.sid, b.bid, b.nameFROM Reserves r FULL OUTER JOIN Boats bON r.bid = b.bid
Returns all boats & all information onreservations
SELECT r.sid, b.bid, b.nameFROM Reserves r FULL OUTER JOIN Boats bON r.bid = b.bid
r.sid b.bid b.name
22 101 Interlake
102 Interlake
95 103 Clipper
104 MarineNote: in this case it is the same as the ROJ becausebid is a foreign key in reserves, so all reservations musthave a corresponding tuple in boats.
INSERT
INSERT INTO Boats VALUES ( 105, ‘Clipper’, ‘purple’)INSERT INTO Boats (bid, color) VALUES (99, ‘yellow’)
“bulk insert” from one table to another (must be type compatible):INSERT INTO TEMP(bid)SELECT r.bid FROM Reserves R WHERE r.sid = 22;
“bulk insert” from files (in Postgres)Copy
INSERT [INTO] table_name [(column_list)]VALUES ( value_list)
INSERT [INTO] table_name [(column_list)]<select statement>
DELETE & UPDATE
DELETE FROM Boats WHERE color = ‘red’
DELETE FROM Boats bWHERE b. bid = (SELECT r.bid FROM Reserves R WHERE r.sid = 22)
Can also modify tuples using UPDATE statement.UPDATE BoatsSET Color = “green”WHERE bid = 103;
DELETE [FROM] table_name[WHERE qualification]
Null Values
• Values are sometimes– unknown (e.g., a rating has not been assigned or– inapplicable (e.g., no spouse’s name).– SQL provides a special value null for such situations.
• The presence of null complicates many issues. E.g.:– Special operators needed to check if value is/is not null.– “rating>8” - true or false when rating is null? What about
AND, OR and NOT connectives?– Need a 3-valued logic (true, false and unknown).– Meaning of constructs must be defined carefully. (e.g.,
WHERE clause eliminates rows that don’t evaluate to true.)– New operators (in particular, outer joins) possible/needed.
Null Values – 3 Valued Logic
NULL
F
T
NullFTAND
(null > 0)
(null + 1)
(null = 0)
null AND true
is null
is null
is null
is null
NULL
F
T
NullFTOR
T
F Null
T F
F F
Null
NullF
F
T T
T
T NullNullNull