This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
What is the effect of replacing S.sid by S.sname in the SELECT clause? Since two sailors may have the same name, some sailor may have no reservation even his/her name is in the output
Find names of sailors who’ve reserved a red and a green boat
SELECT S.name
FROM Sailors S, Boats B1, Reserves R1,
Boats B2, Reserves R2
WHERE S.sid=R1.sid AND R1.bid=B1.bid The sailor reserves 1st boat
AND S.sid=R2.sid AND R2.bid=B2.bid The same sailor reserves 2nd boat
AND (B1.color=‘red’ AND B2.color=‘green’)
The 1st boat is red
The 2nd boat is green
Sailors(sid, sname, rating, age)
Reserves(sid, bid, day)
Boats(bid, bname, color)
Foreign key
Foreign key
Find names of sailors who’ve reserved a red and a green boat
INTERSECT: Can be used to compute the intersection of any two union-compatible sets of tuples.
Included in the SQL/92 standard, but some systems don’t support it.
SELECT S.name
FROM Sailors S, Boats B, Reserves R
WHERE S.sid=R.sid AND R.bid=B.bid
AND B.color=‘red’INTERSECT
SELECT S.name
FROM Sailors S, Boats B, Reserves R
WHERE S.sid=R.sid AND R.bid=B.bid
AND B.color=‘green’
Name of sailors who’ve reserved
red boats
Name of sailors who’ve reserved
green boats
Nested Queries
A very powerful feature of SQL: a WHERE clause can itself contain an SQL query! (Actually, so can FROM and HAVING clauses.)
To understand semantics of nested queries, think of a nested loopsevaluation: For each Sailors tuple, check the qualification by computing the subquery.
To find sailors who’ve not reserved #103, use NOT IN.
SELECT S.sname
FROM Sailors S
WHERE S.sid IN (SELECT R.sid
FROM Reserves R
WHERE R.bid=103)
Find names of sailors who’ve reserved boat #103
Sailor S has at least one of these reservations
Query: Find names of sailors who’ve
reserved boat #103
Nested Queries with Correlation (1)
EXISTS tests whether a set is nonempty.SELECT S.sname
FROM Sailors SWHERE EXISTS (SELECT *
FROM Reserves RWHERE S.sid=R.sid AND R.bid=103)
Sailor S reserves boat 103
NOT EXIST
SELECT S.snameFROM Sailors SWHERE NOT EXISTS (SELECT *
FROM Reserves RWHERE R.bid=103 AND S.sid=R.sid)
Query: Find names of sailors who’ve
never reserved boat #103
Sailor S reserves boat 103
Query: Find names of sailors who
reserve boat 103 at most once.
Nested Queries with Correlation (2)
UNIQUE returns true if no row appears more than once.
(Note: returns true if answer is empty)
Can we replace “SELECT R.bid” by “ SELECT * ” ?
No, A sailor may reserve boat 103 on different days; and
SELECT S.rating, MIN (S.age)FROM Sailors SWHERE S.age > 18GROUP BY S.ratingHAVING 1 ˂ (SELECT COUNT (*)
FROM Sailors S2WHERE S.rating = S2.rating)
Find the age of the youngest sailor older than 18, for each rating with at least 2 sailors
1) Find all sailors older than 18
2) Group qualified sailors according to rating
3.2) Discard groups with less than two sailors
4) Find youngest age for each qualified group
3.1) Count the number of sailors in a group
Number of sailorswith this rating
14
32
Find the age of the youngest sailor older than 18, for each rating level that has at least 2 sailors
Shows HAVING clause can also contain a subquery.
We can use S.rating inside the nested subquery because it has a single value for the current group of sailors.
What if HAVING clause is replaced by “HAVING COUNT(*) >1” Find the age of the youngest sailor older than 18, for each rating level that
has at least two such sailors. /* see next page
SELECT S.rating, MIN (S.age)FROM Sailors SWHERE S.age > 18GROUP BY S.ratingHAVING 1 ˂ (SELECT COUNT (*)
FROM Sailors S2WHERE S.rating = S2.rating)
Replacing this by“HAVING COUNT(*) > 1”
Find the age of the youngest sailor older than 18, for each rating level that has at least 2 sailors
SELECT S.rating, MIN (S.age)FROM Sailors SWHERE S.age > 18GROUP BY S.ratingHAVING 1 ˂ (SELECT COUNT (*)
FROM Sailors S2WHERE S.rating = S2.rating)
Counting including sailors younger
than 18
At least 2 sailors
SELECT S.rating, MIN (S.age)FROM Sailors SWHERE S.age > 18GROUP BY S.ratingHAVING COUNT (*) › 1
Counting include only adult sailors
At least 2 such sailors, i.e., older than 18
“age” is notmentioned in this subquery
Find those ratings for which the average
age is the minimum over all ratings
SELECT S.rating
FROM Sailors S
WHERE S.age = (SELECT MIN (AVG (S2.age))
FROM Sailors S2)
Aggregate operations cannot
be nested
Find those ratings for which the average
age is the minimum over all ratings
SELECT Temp.rating, Temp.avgage
FROM (SELECT S.rating, AVG (S.age) AS avgage
FROM Sailors S
GROUP BY S.rating) AS Temp
WHERE Temp.avgage = (SELECT MIN (Temp.avgage)
FROM Temp)
Correct solution (in SQL/92):
Minimum over all ratings
Find average age for each rating group.
This table hastwo columns
Average age for some rating group
Output this rating group and its average age
Null Values
Field values in a tuple 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.
Null Values
The presence of null complicates many issues:
Special operators needed, e.g., IS NULL to test if a value is null.
Is rating>8 true or false when rating is equal to null? null
What about AND, OR and NOT ? Need a 3-valued logic (true, false,and unknown), e.g., (unknown OR false) = unknown.
Meaning of constructs must be defined carefully, e.g., WHERE clause eliminates rows that don’t evaluate to true. Null + 5 = null; but SUM (null, 5) = 5. (nulls can cause some unexpected
behavior)
New operators (in particular, outer joins) possible/needed.
Outer Joins
sid bid day
22 101 10/10/96
58 103 11/12/96
R1
sid sname rating age
22 dustin 7 45.0
31 lubber 8 55.5
58 rusty 10 35.0
S1
S1 R1 sid sname rating age bid day
22 dustin 7 45.0 101 10/10/96
31 lubber 8 55.55 null null
58 rusty 10 35.0 103 11/12/96
No match in
R1
No “sid = 31”
Integrity Constraints (Review) An IC describes conditions that every legal instance of a
relation must satisfy.
Inserts/deletes/updates that violate IC’s are disallowed.
Can be used to ensure application semantics (e.g., sid is a key), or prevent inconsistencies (e.g., sname has to be a string, agemust be < 200)
Types of IC’s: Domain constraints, primary key constraints, foreign key constraints, general constraints.
Domain constraints: Field values must be of right type. Always enforced.
We have not discussed this
General Constraints
Useful when more general ICs than keys are involved.
BEFORE INSERT ON SAILORSFOR EACH STATEMENTINSERT INTO CountTable
SET count = 0WHERE age = 18
CREATE TRIGGER IncrCountAFTER INSERT ON SAILORSREFERENCING NEW AS newrowWHEN newrow.age = 18 FOR EACH ROW
UPDATE CountTableSET count = count + 1WHERE age = 18
Statement-level trigger (default):
Execute trigger only once to initialize counter
Row-level trigger:
Evaluate each new sailor to decide whether to increment the counter
CountTable
age count
17 113
18 229...
.
.
.
99 2
Statement-Level Trigger Example (SQL:1999)
CREATE TRIGGER youngSailorUpdate
AFTER INSERT ON SAILORS /* Event
REFERENCING NEW TABLE AS NewSailors
FOR EACH STATEMENT /* Statement-level trigger (default)
INSERT /* Action
INTO YoungSailors(sid, name, age, rating)
SELECT sid, name, age, rating
FROM NewSailors N
WHERE N.age <= 18
Give a table name to the set of newly inserted tuples
Maintain information on young sailors in a separate YoungSailorstable
SailorsNewSailors
≤ 18 YoungSailors
TRIGGER
New tuples
Row-Level Trigger Example (SQL:1999)
CREAT TRIGGER RatingTrigger
AFTER UPDATE OF rating ON Sailors
REFERENCING
OLD AS OldTuple, /* value before update
NEW AS NewTuple /* value after update
WHEN (OldTupple.rating ˃ NewTupple.rating)
FOR EACH ROW
UPDATE Sailors
SET rating = OldTuple.rating
WHERE SID = NewTuple.SID
/* Row-level trigger
/* Condition
/* Event
/* Action: Restore
/* any attempt to
/* lower rating
Sailors(SID, sname, rating, age)
Summary SQL was an important factor in the early acceptance of
the relational model; more natural than earlier, procedural query languages.
Relationally complete; in fact, significantly more expressive power than relational algebra.
Even queries that can be expressed in RA can often be expressed more naturally in SQL.
Many alternative ways to write a query; optimizer should look for most efficient evaluation plan. In practice, users need to be aware of how queries are
optimized and evaluated for best results.
Summary (Contd.) NULL for unknown-field values brings many
complications
SQL allows specification of rich integrity constraints
Triggers respond to changes in the database
Homework #5
Practice the 50+ SQL examples in Chapter 5
Do the following exercises:
Exercise 5.4.2 (Fulltime is 40 hours, Hint: Use SELECT in HAVING clause)
Exercise 5.4.3 (Hint: Use “ALL” and nested SELECT)
Exercise 5.8.2.e (Hint: Use an assertion with “NOT IN”)
Exercise 5.10.3 (Hint: Add CHECK statement to the Workstable.)