数据库系统概念答案第六版(全)

第三章

C H A P T E R 3
Introduction to SQL
Exercises
3.1 Write the following queries in SQL, using the university schema. (We suggest you actually run these queries on a database, using the sample data
that we provide on the Web site of the book, db-book.com. Instructions for
setting up a database, and loading sample data, are provided on the above
Web site.)
a. Find the titles of courses in the Comp. Sci. department that have 3
credits.
b. Find the IDs of all students who were taught by an instructor named
Einstein; make sure there are no duplicates in the result.
c. Find the highest salary of any instructor.
d. Find all instructors earning the highest salary (there may be more
than one with the same salary).
e. Find the enrollment of each section that was offered in Autumn 2009.
f. Find the maximum enrollment, across all sections, in Autumn 2009.
g. Find the sections that had the maximum enrollment in Autumn 2009.
Answer:
a. Find the titles of courses in the Comp. Sci. department that have 3
credits.
select title
from course
where dept name = ’Comp. Sci.’
and credits = 3
5
6 Chapter 3 Introduction to SQL
b. Find the IDs of all students who were taught by an instructor named
Einstein; make sure there are no duplicates in the result.
This query can be answered in several different ways. One way is as
follows.
select distinct student.ID
from (student join takes using(ID))
join (instructor join teaches using(ID))
using(course id, sec id, semester, year)
where instructor.name = ’Einstein’
As an alternative to th join … using syntax above the query can be
written by enumerating relations in the from clause, and adding the
corresponding join predicates on ID, course id,section id,semester, and
year to the where clause.
Note that using natural join in place of join … using would result in
equating student ID with instructor ID, which is incorrect.
c. Find the highest salary of any instructor.
select max(salary)
from instructor
d. Find all instructors earning the highest salary (there may be more
than one with the same salary).
select ID, name
from instructor
where salary = (select max(salary) from instructor)
e. Find the enrollment of each section that was offered in Autumn 2009.
One way of writing the query is as follows.
select course id, sec id, count(ID)
from section natural join takes
where semester = ’Autumn’
and year = 2009
group by course id, sec id
Note that if a section does not have any students taking it, it would
not appear in the result. One way of ensuring such a section appears
with a count of 0 is to replace natural join by the natural left outer
join operation, covered later in Chapter 4. Another way is to use a
subquery in the select clause, as follows.
Exercises 7
select course id, sec id, (select count(ID)
from takes
where takes.year = section.year
and takes.semester = section.semester
and takes.course id = section.course id
and takes.section id = section.section id)
from section
where semester = ’Autumn’
and year = 2009
Note that if the result of the subquery is empty, the aggregate function count returns a value of 0.
f. Find the maximum enrollment, across all sections, in Autumn 2009.
One way of writing this query is as follows:
select max(enrollment)
from (select count(ID) as enrollment
from section natural join takes
where semester = ’Autumn’
and year = 2009
group by course id, sec id)
As an alternative to using a nested subquery in the from clause, it is
possible to use a with clause, as illustrated in the answer to the next
part of this question.
A subtle issue in the above query is that if no section had any enrollment, the answer would be empty, not 0. We can use the alternative
using a subquery, from the previous part of this question, to ensure
the count is 0 in this case.
g. Find the sections that had the maximum enrollment in Autumn 2009.
The following answer uses a with clause to create a temporary view,
simplifying the query.
with sec enrollment as (
select course id, sec id, count(ID) as enrollment
from section natural join takes
where semester = ’Autumn’
and year = 2009
group by course id, sec id)
select course id, sec id
from sec enrollment
where enrollment = (select max(enrollment) from sec enrollment)
It is also possible to write the query without the with clause, but the
subquery to find enrollment would get repeated twice in the query.
8 Chapter 3 Introduction to SQL

3.2 Suppose you are given a relation grade points(grade, points), which provides
a conversion from letter grades in the takes relation to numeric scores; for
example an “A” grade could be specified to correspond to 4 points, an “A−”
to 3.7 points, a “B+” to 3.3 points, a “B” to 3 points, and so on. The grade
points earned by a student for a course offering (section) is defined as the
number of credits for the course multiplied by the numeric points for the
grade that the student received.
Given the above relation, and our university schema, write each of the
following queries in SQL. You can assume for simplicity that no takes tuple
has the null value for grade.
a. Find the total grade-points earned by the student with ID 12345,
across all courses taken by the student.
b. Find the grade-point average (GPA) for the above student, that is,
the total grade-points divided by the total credits for the associated
courses.
c. Find the ID and the grade-point average of every student.
Answer:
a. Find the total grade-points earned by the student with ID 12345,
across all courses taken by the student.
select sum(credits * points)
from (takes natural join course) natural join grade points
whereID = ’12345’
One problem with the above query is that if the student has not
taken any course, the result would not have any tuples, whereas we
would expect to get 0 as the answer. One way of fixing this problem
is to use the natural left outer join operation, which we study later
in Chapter 4. Another way to ensure that we get 0 as the answer, is
to the following query:
(select sum(credits * points)
from (takes natural join course) natural join grade points
where ID = ’12345’)
union
(select 0
from student
where takes.ID = ’12345’ and
not exists ( select * from takes where takes.ID = ’12345’))
As usual, specifying join conditions can be specified in the where
clause instead of using the natural join operation or the join … using
operation.
Exercises 9
b. Find the grade-point average (GPA) for the above student, that is,
the total grade-points divided by the total credits for the associated
courses.
select sum(credits * points)/sum(credits) as GPA
from (takes natural join course) natural join grade points
where ID = ’12345’
As before, a student who has not taken any course would not appear
in the above result; we can ensure that such a student appears in the
result by using the modified query from the previous part of this
question. However, an additional issue in this case is that the sum
of credits would also be 0, resulting in a divide by zero condition.
In fact, the only meaningful way of defining the GPA in this case is
to define it as null. We can ensure that such a student appears in the
result with a null GPA by adding the following union clause to the
above query.
union
(select null as GPA
from student
where takes.ID = ’12345’ and
not exists ( select * from takes where takes.ID = ’12345’))
Other ways of ensuring the above are discussed later in the solution
to Exercise 4.5.
c. Find the ID and the grade-point average of every student.
select ID, sum(credits * points)/sum(credits) as GPA
from (takes natural join course) natural join grade points
group by ID
Again, to handle students who have not taken any course, we would
have to add the following union clause:
union
(select ID, null as GPA
from student
where not exists ( select * from takes where takes.ID = student.ID))

3.3
3.4 Write the following inserts, deletes or updates in SQL, using the university
schema.
a. Increase the salary of each instructor in the Comp. Sci. department
by 10%.
b. Delete all courses that have never been offered (that is, do not occur
in the section relation).
10 Chapter 3 Introduction to SQL
c. Insert every student whose tot cred attribute is greater than 100 as an
instructor in the same department, with a salary of $10,000.
Answer:
a. Increase the salary of each instructor in the Comp. Sci. department
by 10%.
update instructor
set salary = salary * 1.10
where dept name = ’Comp. Sci.’
b. Delete all courses that have never been offered (that is, do not occur
in the section relation).
delete from course
where course id not in
(select course id from section)
c. Insert every student whose tot cred attribute is greater than 100 as an
instructor in the same department, with a salary of $10,000.
insert into instructor
select ID, name, dept name, 10000
from student
where tot cred > 100

3.5 Consider the insurance database of Figure ??, where the primary keys
are underlined. Construct the following SQL queries for this relational
database.
a. Find the total number of people who owned cars that were involved
in accidents in 1989.
b. Add a new accident to the database; assume any values for required
attributes.
c. Delete the Mazda belonging to “John Smith”.
Answer: Note: The participated relation relates drivers, cars, and accidents.
a. Find the total number of people who owned cars that were involved
in accidents in 1989.
Note: this is not the same as the total number of accidents in 1989.
We must count people with several accidents only once.
select count (distinct name)
from accident, participated, person
where accident.report number = participated.report number
and participated.driver id = person.driver id
and date between date ’1989-00-00’ and date ’1989-12-31’
Exercises 11
person (driver id, name, address)
car (license, model, year)
accident (report number, date, location)
owns (driver id, license)
participated (driver id, car, report number, damage amount)
Figure ??. Insurance database.
b. Add a new accident to the database; assume any values for required
attributes.
We assume the driver was “Jones,” although it could be someone
else. Also, we assume “Jones” owns one Toyota. First we must find
the license of the given car. Then the participated and accidentrelations
must be updated in order to both record the accident and tie it to the
given car. We assume values “Berkeley” for location, ’2001-09-01’ for
date and date, 4007 for report number and 3000 for damage amount.
insert into accident
values (4007, ’2001-09-01’, ’Berkeley’)
insert into participated
select o.driver id, c.license, 4007, 3000
from person p, owns o, car c
where p.name = ’Jones’ and p.driver id = o.driver id and
o.license = c.license and c.model = ’Toyota’
c. Delete the Mazda belonging to “John Smith”.
Since model is not a key of the car relation, we can either assume
that only one of John Smith’s cars is a Mazda, or delete all of John
Smith’s Mazdas (the query is the same). Again assume name is a key
for person.
delete car
where model = ’Mazda’ and license in
(select license
from person p, owns o
where p.name = ’John Smith’ and p.driver id = o.driver id)
Note: The owns, accident and participated records associated with the
Mazda still exist.

3.11 Write the following queries in SQL, using the university schema.
a. Find the names of all students who have taken at least one Comp.
Sci. course; make sure there are no duplicate names in the result.
b. Find the IDs and names of all students who have not taken any
course offering before Spring 2009.
11
12 Chapter 3 Introduction to SQL
c. For each department, find the maximum salary of instructors in that
department. You may assume that every department has at least one
instructor.
d. Find the lowest, across all departments, of the per-department maximum salary computed by the preceding query.
Answer:
a. SQL query:
select name
from student natural join takes natural join course
where course.dept = ’Comp. Sci.’
b. SQL query:
select id, name
from student
except
select id, name
from student natural join takes
where year < 2009
Since the except operator eliminates duplicates, there is no need
to use a select distinct clause, although doing so would not affect
correctness of the query.
c. SQL query:
select dept, max(salary)
from instructor
group by dept
d. SQL query:
select min(maxsalary)
from (select dept, max(salary) as maxsalary
from instructor
group by dept)

3.12 Write the following queries in SQL, using the university schema.
a. Create a new course “CS-001”, titled “Weekly Seminar”, with 0 credits.
Exercises 13
b. Create a section of this course in Autumn 2009, with section id of 1.
c. Enroll every student in the Comp. Sci. department in the above
section.
d. Delete enrollments in the above section where the student’s name is
Chavez.
e. Delete the course CS-001. What will happen if you run this delete
statement without first deleting offerings (sections) of this course.
f. Delete all takes tuples corresponding to any section of any course
with the word “database” as a part of the title; ignore case when
matching the word with the title.
Answer:
a. SQL query:
insert into course
values (’CS-001’, ’Weekly Seminar’, ’Comp. Sci.’, 0)
b. SQL query:
insert into section
values (’CS-001’, 1, ’Autumn’, 2009, null, null, null)
Note that the building, roomnumber and slot were not specified in
the question, and we have set them to null. The same effect would
be obtained if they were specified to default to null, and we simply
omitted values for these attributes in the above insert statement.
(Many database systems implicitly set the default value to null, even
if not explicitly specified.)
c. SQL query:
insert into takes
select id, ’CS-001’, 1, ’Autumn’, 2009, null
from student
where dept name = ’Comp. Sci.’
d. SQL query:
14 Chapter 3 Introduction to SQL
delete from takes
where course id= ’CS-001’ and section id = 1 and
year = 2009 and semester = ’Autumn’ and
id in (select id
from student
where name = ’Chavez’)
Note that if there is more than one student named Chavez, all such
students would have their enrollments deleted. If we had used =
instead of in, an error would have resulted if there were more than
one student named Chavez.
e. SQL query:
delete from takes
where course id = ’CS-001’
delete from section
where course id = ’CS-001’
delete from course
where course id = ’CS-001’
If we try to delete the course directly, there will be a foreign key violation because section has a foriegn key reference to course; similarly,
we have to delete corresponding tuples from takes before deleting
sections, since there is a foreign key reference from takes to section.
As a result of the foreign key violation, the transaction that performs
the delete would be rolled back.
f. SQL query:
delete from takes
where course id in
(select course id
from course
where lower(title) like ’%database%’)

3.13 Write SQL DDL corresponding to the schema in Figure 3.18. Make any
reasonable assumptions about data types, and be sure to declare primary
and foreign keys.
Answer:
a. SQL query:
Exercises 15
person (driver id, name, address)
car (license, model, year)
accident (report number, date, location)
owns (driver id, license)
participated (report number, license, driver id, damage amount)
Figure 3.18 Insurance database for Exercises 3.4 and 3.14.
create table person
(driver id varchar(50),
name varchar(50),
address varchar(50),
primary key (driver id))
b. SQL query:
create table car
(license varchar(50),
model varchar(50),
year integer,
primary key (license))
c. SQL query:
create table accident
(report number integer,
date date,
location varchar(50),
primary key (report number))
d. SQL query:
create table owns
(driver id varchar(50),
license varchar(50),
primary key (driver id,license)
foriegn key (driver id) references person
foriegn key (license) references car)
e. SQL query:
16 Chapter 3 Introduction to SQL
create table participated
(report number integer,
license varchar(50),
driver id varchar(50),
damage amountinteger,
primary key (report number,license)
foriegn key (license) references car
foriegn key (report number) references accident))

3.14 Consider the insurance database of Figure 3.18, where the primary keys
are underlined. Construct the following SQL queries for this relational
database.
a. Find the number of accidents in which the cars belonging to “John
Smith” were involved.
b. Update the damage amount for the car with license number “AABB2000”
in the accident with report number “AR2197” to $3000.
Answer: Note: The participated relation relates drivers, cars, and accidents.
a. SQL query:
select count (*)
from accident
where exists
(select *
from participated, owns, person
where owns.driver id = person.driver id
and person.name = ’John Smith’
and owns.license = participated.license
and accident.report number = participated.report number)
The query can be written in other ways too; for example without a
subquery, by using a join and selecting count( distinctreport number)
to get a count of number of accidents involving the car.
b. SQL query:
update participated
set damage amount = 3000
where report number = “AR2197” and
license = “AABB2000”)

3.15 Consider the bank database of Figure 3.19, where the primary keys are underlined. Construct the following SQL queries for this relational database.
Exercises 17
branch(branch name, branch city, assets)
customer (customer name, customer street, customer city)
loan (loan number, branch name, amount)
borrower (customer name, loan number)
account (account number, branch name, balance )
depositor (customer name, account number)
Figure 3.19 Banking database for Exercises 3.8 and 3.15.
a. Find all customers who have an account at all the branches located
in “Brooklyn”.
b. Find out the total sum of all loan amounts in the bank.
c. Find the names of all branches that have assets greater than those of
at least one branch located in “Brooklyn”.
Answer:
a. SQL query:
with branchcount as
(select count(*)
branch
where branch city = ’Brooklyn’)
select customer name
from customer c
where branchcount = (select count(distinct branch name)
from (customer natural join depositor natural join account
natural join branch) as d
where d.customer name = c.customer name)
There are other ways of writing this query, for example by first
finding customers who do not have an account at some branch in
Brooklyn, and then removing these customers from the set of all
customers by using an except clause.
b. SQL query:
select sum(amount)
from loan
c. SQL query:
18 Chapter 3 Introduction to SQL
employee (employee name, street, city)
works (employee name, company name, salary)
company (company name, city)
manages (employee name, manager name)
Figure 3.20 Employee database for Exercises 3.9, 3.10, 3.16, 3.17, and 3.20.
select branch name
from branch
where assets > some
(select assets
from branch
where branch city = ’Brooklyn’)
The keyword any could be used in place of some above.

3.16 Consider the employee database of Figure 3.20, where the primary keys are
underlined. Give an expression in SQL for each of the following queries.
a. Find the names of all employees who work for First Bank Corporation.
b. Find all employees in the database who live in the same cities as the
companies for which they work.
c. Find all employees in the database who live in the same cities and
on the same streets as do their managers.
d. Find all employees who earn more than the average salary of all
employees of their company.
e. Find the company that has the smallest payroll.
Answer:
a. Find the names of all employees who work for First Bank Corporation.
select employee name
from works
where company name = ’First Bank Corporation’
b. Find all employees in the database who live in the same cities as the
companies for which they work.
select e.employee name
from employee e, works w, company c
where e.employee name = w.employee name and e.city = c.city and
w.company name = c.company name
Exercises 19
c. Find all employees in the database who live in the same cities and
on the same streets as do their managers.
select P.employee name
from employee P, employee R, manages M
where P.employee name = M.employee name and
M.manager name = R.employee name and
P.street = R.street and P.city = R.city
d. Find all employees who earn more than the average salary of all
employees of their company.
select employee name
from works T
where salary > (select avg (salary)
from works S
where T.company name = S.company name)
The primary key constraint on works ensures that each person works
for at most one company.
e. Find the company that has the smallest payroll.
select company name
from works
group by company name
having sum (salary) <= all (select sum (salary)
from works
group by company name)

链接

资源链接
数据库系统概念答案第六版(全)
答案全,含实践习题与习题

你可能感兴趣的:(生活,数据库)