5 1 5
5 1 5
Online material is available for all exercises in this chapter on the books webpage at
http://www.cs.wisc.edu/~ dbbook
This includes scripts to create tables for each exercise for use with Oracle, IBM DB2,
Microsoft SQL Server, Microsoft Access and MySQL.
Exercise 5.1 Consider the following relations:
Student(snum: integer, sname: string, major: string, level: string, age: integer)
Class(name: string, meets at: string, room: string, d: integer)
Enrolled(snum: integer, cname: string)
Faculty(d: integer, fname: string, deptid: integer)
The meaning of these relations is straightforward; for example, Enrolled has one record
per student-class pair such that the student is enrolled in the class.
Write the following queries in SQL. No duplicates should be printed in any of the
answers.
1. Find the names of all Juniors (level = JR) who are enrolled in a class taught by
I. Teach.
2. Find the age of the oldest student who is either a History major or enrolled in a
course taught by I. Teach.
3. Find the names of all classes that either meet in room R128 or have ve or more
students enrolled.
4. Find the names of all students who are enrolled in two classes that meet at the
same time.
59
60
Chapter 5
5. Find the names of faculty members who teach in every room in which some class
is taught.
6. Find the names of faculty members for whom the combined enrollment of the
courses that they teach is less than ve.
7. For each level, print the level and the average age of students for that level.
8. For all levels except JR, print the level and the average age of students for that
level.
9. For each faculty member that has taught classes only in room R128, print the
faculty members name and the total number of classes she or he has taught.
10. Find the names of students enrolled in the maximum number of classes.
11. Find the names of students not enrolled in any class.
12. For each age value that appears in Students, nd the level value that appears most
often. For example, if there are more FR level students aged 18 than SR, JR, or
SO students aged 18, you should print the pair (18, FR).
Answer 5.1 The answers are given below:
1.
2.
SELECT MAX(S.age)
FROM
Student S
WHERE (S.major = History)
OR S.snum IN (SELECT E.snum
FROM
Class C, Enrolled E, Faculty F
WHERE E.cname = C.name AND C.d = F.d
AND F.fname = I.Teach )
3.
SELECT
FROM
WHERE
C.name
Class C
C.room = R128
OR C.name IN (SELECT
FROM
GROUP BY
HAVING
E.cname
Enrolled E
E.cname
COUNT (*) >= 5)
61
4.
5.
6.
SELECT
FROM
WHERE
7.
SELECT
S.level, AVG(S.age)
FROM
Student S
GROUP BY S.level
8.
SELECT
FROM
WHERE
GROUP BY
S.level, AVG(S.age)
Student S
S.level <> JR
S.level
9.
SELECT
FROM
WHERE
GROUP BY
HAVING
SELECT
FROM
WHERE
DISTINCT S.sname
Student S
S.snum IN (SELECT E.snum
FROM
Enrolled E
GROUP BY E.snum
10.
DISTINCT F.fname
Faculty F
5 > (SELECT COUNT (E.snum)
FROM
Class C, Enrolled E
WHERE C.name = E.cname
AND
C.d = F.d)
62
Chapter 5
HAVING
11.
12.
SELECT
FROM
GROUP BY
HAVING
S.age, S.level
Student S
S.age, S.level,
S.level IN (SELECT
FROM
WHERE
GROUP BY
HAVING
S1.level
Student S1
S1.age = S.age
S1.level, S1.age
COUNT (*) >= ALL (SELECT
COUNT (*)
FROM
Student S2
WHERE s1.age = S2.age
GROUP BY S2.level, S2.age))
63
10. For every supplier that only supplies green parts, print the name of the supplier
and the total number of parts that she supplies.
11. For every supplier that supplies a green part and a red part, print the name and
price of the most expensive part that she supplies.
Answer 5.2 The answers are given below:
1.
2.
SELECT S.sname
FROM
Suppliers S
WHERE NOT EXISTS (( SELECT
FROM
EXCEPT
( SELECT
FROM
WHERE
3.
SELECT S.sname
FROM
Suppliers S
WHERE NOT EXISTS (( SELECT
FROM
WHERE
EXCEPT
( SELECT
FROM
WHERE
4.
SELECT
FROM
WHERE
AND
AND
5.
P.pid
Parts P )
C.pid
Catalog C
C.sid = S.sid ))
P.pid
Parts P
P.color = Red )
C.pid
Catalog C, Parts P
C.sid = S.sid AND
C.pid = P.pid AND P.color = Red ))
P.pname
Parts P, Catalog C, Suppliers S
P.pid = C.pid AND C.sid = S.sid
S.sname = Acme Widget Suppliers
NOT EXISTS ( SELECT *
FROM
Catalog C1, Suppliers S1
WHERE P.pid = C1.pid AND C1.sid = S1.sid AND
S1.sname <> Acme Widget Suppliers )
64
6.
Chapter 5
WHERE
SELECT
FROM
WHERE
AND
AND
P.pid, S.sname
Parts P, Suppliers
C.pid = P.pid
C.sid = S.sid
C.cost = (SELECT
FROM
WHERE
S, Catalog C
MAX (C1.cost)
Catalog C1
C1.pid = P.pid)
7.
8.
9.
SELECT
FROM
WHERE
UNION
SELECT
FROM
WHERE
DISTINCT C.sid
Catalog C, Parts P
C.pid = P.pid AND P.color = Red
DISTINCT C1.sid
Catalog C1, Parts P1
C1.pid = P1.pid AND P1.color = Green
10.
SELECT
FROM
WHERE
GROUP BY
HAVING
11.
SELECT
FROM
WHERE
65
Exercise 5.3 The following relations keep track of airline ight information:
Flights(no: integer, from: string, to: string, distance: integer,
departs: time, arrives: time, price: real)
Aircraft(aid: integer, aname: string, cruisingrange: integer)
Certied(eid: integer, aid: integer)
Employees(eid: integer, ename: string, salary: integer)
Note that the Employees relation describes pilots and other kinds of employees as well;
every pilot is certied for some aircraft, and only pilots are certied to y. Write each
of the following queries in SQL. (Additional queries using the same schema are listed
in the exercises for Chapter 4.)
1. Find the names of aircraft such that all pilots certied to operate them have
salaries more than $80,000.
2. For each pilot who is certied for more than three aircraft, nd the eid and the
maximum cruisingrange of the aircraft for which she or he is certied.
3. Find the names of pilots whose salary is less than the price of the cheapest route
from Los Angeles to Honolulu.
4. For all aircraft with cruisingrange over 1000 miles, nd the name of the aircraft
and the average salary of all pilots certied for this aircraft.
5. Find the names of pilots certied for some Boeing aircraft.
6. Find the aids of all aircraft that can be used on routes from Los Angeles to
Chicago.
7. Identify the routes that can be piloted by every pilot who makes more than
$100,000.
8. Print the enames of pilots who can operate planes with cruisingrange greater than
3000 miles but are not certied on any Boeing aircraft.
9. A customer wants to travel from Madison to New York with no more than two
changes of ight. List the choice of departure times from Madison if the customer
wants to arrive in New York by 6 p.m.
10. Compute the dierence between the average salary of a pilot and the average
salary of all employees (including pilots).
66
Chapter 5
11. Print the name and salary of every nonpilot whose salary is more than the average
salary for pilots.
12. Print the names of employees who are certied only on aircrafts with cruising
range longer than 1000 miles.
13. Print the names of employees who are certied only on aircrafts with cruising
range longer than 1000 miles, but on at least two such aircrafts.
14. Print the names of employees who are certied only on aircrafts with cruising
range longer than 1000 miles and who are certied on some Boeing aircraft.
Answer 5.3 The answers are given below:
1.
2.
SELECT
FROM
WHERE
GROUP BY
HAVING
3.
4. Observe that aid is the key for Aircraft, but the question asks for aircraft names;
we deal with this complication by using an intermediate relation Temp:
SELECT Temp.name, Temp.AvgSalary
FROM
( SELECT
A.aid, A.aname AS name,
AVG (E.salary) AS AvgSalary
FROM
Aircraft A, Certied C, Employees E
WHERE
A.aid = C.aid AND
C.eid = E.eid AND A.cruisingrange > 1000
GROUP BY A.aid, A.aname ) AS Temp
67
5.
6.
SELECT A.aid
FROM
Aircraft A
WHERE A.cruisingrange > ( SELECT MIN (F.distance)
FROM
Flights F
WHERE F.from = Los Angeles AND F.to = Chicago )
7.
8.
9.
SELECT F.departs
FROM
Flights F
WHERE F.no IN ( ( SELECT F0.no
68
Chapter 5
FROM
WHERE
Flights F0
F0.from = Madison AND F0.to = New York
AND F0.arrives < 18:00 )
UNION
( SELECT F0.no
FROM
Flights F0, Flights F1
WHERE F0.from = Madison AND F0.to <> New York
AND F0.to = F1.from AND F1.to = New York
AND F1.departs > F0.arrives
AND F1.arrives < 18:00 )
UNION
( SELECT F0.no
FROM
Flights F0, Flights F1, Flights F2
WHERE F0.from = Madison
AND F0.to = F1.from
AND F1.to = F2.from
AND F2.to = New York
AND F0.to <> New York
AND F1.to <> New York
AND F1.departs > F0.arrives
AND F2.departs > F1.arrives
AND F2.arrives < 18:00 ))
10.
11.
12.
SELECT
E.ename
69
FROM
WHERE
GROUP BY
HAVING
13.
SELECT
FROM
WHERE
GROUP BY
HAVING
E.ename
Employees E, Certied C, Aircraft A
C.aid = A.aid AND E.eid = C.eid
E.eid, E.ename
EVERY (A.cruisingrange > 1000) AND COUNT (*) > 1
14.
SELECT
FROM
WHERE
GROUP BY
HAVING
E.ename
Employees E, Certied C, Aircraft A
C.aid = A.aid AND E.eid = C.eid
E.eid, E.ename
EVERY (A.cruisingrange > 1000) AND ANY (A.aname = Boeing)
Exercise 5.4 Consider the following relational schema. An employee can work in
more than one department; the pct time eld of the Works relation shows the percentage of time that a given employee works in a given department.
Emp(eid: integer, ename: string, age: integer, salary: real)
Works(eid: integer, did: integer, pct time: integer)
Dept(did: integer, dname: string, budget: real, managerid: integer)
Write the following queries in SQL:
1. Print the names and ages of each employee who works in both the Hardware
department and the Software department.
2. For each department with more than 20 full-time-equivalent employees (i.e., where
the part-time and full-time employees add up to at least that many full-time
employees), print the did together with the number of employees that work in
that department.
3. Print the name of each employee whose salary exceeds the budget of all of the
departments that he or she works in.
4. Find the managerids of managers who manage only departments with budgets
greater than $1 million.
5. Find the enames of managers who manage the departments with the largest budgets.
6. If a manager manages more than one department, he or she controls the sum of all
the budgets for those departments. Find the managerids of managers who control
more than $5 million.
70
Chapter 5
2.
SELECT
FROM
GROUP BY
HAVING
3.
SELECT E.ename
FROM
Emp E
WHERE E.salary > ALL (SELECT D.budget
FROM
Dept D, Works W
WHERE E.eid = W.eid AND D.did = W.did)
4.
5.
SELECT E.ename
FROM
Emp E
WHERE E.eid IN (SELECT D.managerid
FROM
Dept D
WHERE D.budget = (SELECT MAX (D2.budget)
FROM Dept D2))
6.
SELECT D.managerid
FROM
Dept D
WHERE 5000000 < (SELECT SUM (D2.budget)
FROM Dept D2
WHERE D2.managerid = D.managerid )
71
sid
sname
rating
age
18
41
22
63
jones
jonah
ahab
moby
3
6
7
null
30.0
56.0
44.0
15.0
Figure 5.1
An Instance of Sailors
7.
8.
SELECT
FROM
WHERE
HAVING
E.ename
Emp E, Dept D
E.eid = D.managerid GROUP BY E.Eid, E.ename
EVERY (D.budget > 1000000) AND ANY (D.budget < 5000000)
Exercise 5.5 Consider the instance of the Sailors relation shown in Figure 5.1.
1. Write SQL queries to compute the average rating, using AVG; the sum of the
ratings, using SUM; and the number of ratings, using COUNT.
2. If you divide the sum just computed by the count, would the result be the same
as the average? How would your answer change if these steps were carried out
with respect to the age eld instead of rating?
3. Consider the following query: Find the names of sailors with a higher rating than
all sailors with age < 21. The following two SQL queries attempt to obtain the
answer to this question. Do they both compute the result? If not, explain why.
Under what conditions would they compute the same result?
SELECT S.sname
FROM
Sailors S
WHERE NOT EXISTS ( SELECT *
FROM
Sailors S2
WHERE S2.age < 21
AND S.rating <= S2.rating )
SELECT *
FROM
Sailors S
72
Chapter 5
WHERE
4. Consider the instance of Sailors shown in Figure 5.1. Let us dene instance S1 of
Sailors to consist of the rst two tuples, instance S2 to be the last two tuples, and
S to be the given instance.
(a) Show the left outer join of S with itself, with the join condition being sid=sid.
(b) Show the right outer join of S with itself, with the join condition being
sid=sid.
(c) Show the full outer join of S with itself, with the join condition being sid=sid.
(d) Show the left outer join of S1 with S2, with the join condition being sid=sid.
(e) Show the right outer join of S1 with S2, with the join condition being sid=sid.
(f) Show the full outer join of S1 with S2, with the join condition being sid=sid.
Answer 5.5 The answers are shown below:
1.
2. The result using SUM and COUNT would be smaller than the result using AVERAGE if there are tuples with rating = NULL. This is because all the aggregate
operators, except for COUNT, ignore NULL values. So the rst approach would
compute the average over all tuples while the second approach would compute the
average over all tuples with non-NULL rating values. However, if the aggregation
is done on the age eld, the answers using both approaches would be the same
since the age eld does not take NULL values.
3. Only the rst query is correct. The second query returns the names of sailors with
a higher rating than at least one sailor with age < 21. Note that the answer to
the second query does not necessarily contain the answer to the rst query. In
particular, if all the sailors are at least 21 years old, the second query will return an
empty set while the rst query will return all the sailors. This is because the NOT
EXISTS predicate in the rst query will evaluate to true if its subquery evaluates
to an empty set, while the ANY predicate in the second query will evaluate to
false if its subquery evaluates to an empty set. The two queries give the same
results if and only if one of the following two conditions hold:
73
sname
rating
age
sid
sname
rating
age
18
41
22
63
jones
jonah
ahab
moby
3
6
7
null
30.0
56.0
44.0
15.0
18
41
22
63
jones
jonah
ahab
moby
3
6
7
null
30.0
56.0
44.0
15.0
(b)
sid
18
41
22
63
sname
jones
jonah
ahab
moby
rating
3
6
7
null
age
30.0
56.0
44.0
15.0
sid
18
41
22
63
sname
jones
jonah
ahab
moby
rating
3
6
7
null
age
30.0
56.0
44.0
15.0
(c)
sid
18
41
22
63
sname
jones
jonah
ahab
moby
rating
3
6
7
null
age
30.0
56.0
44.0
15.0
sid
18
41
22
63
sname
jones
jonah
ahab
moby
rating
3
6
7
null
age
30.0
56.0
44.0
15.0
4. (a)
(d)
(e)
(f)
sid
18
41
sname
jones
jonah
rating
3
6
age
30.0
56.0
sid
null
null
sname
null
null
rating
null
null
age
null
null
sid
sname
rating
age
sid
sname
rating
age
null
null
null
null
null
null
null
null
22
63
ahab
moby
7
null
44.0
15.0
sid
sname
rating
age
sid
sname
rating
age
18
41
null
null
jones
jonah
null
null
3
6
null
null
30.0
56.0
null
null
null
null
22
63
null
null
ahab
moby
null
null
7
null
null
null
44.0
15.0