CHAPTER 8: SQL-99: SCHEMA
DEFINITION, BASIC CONSTRAINTS, AND QUERIES
Answers to Selected Exercises
8. 7 Consider the database shown in
Figure 1.2, whose schema is shown in Figure 2.1.
What are the referential integrity
constraints that should hold on the schema?
Write appropriate SQL DDL statements
to define the database.
Answer:
The following referential integrity
constraints should hold (we use the notation:
R.(A1, ..., An) --> S.(B1, ...,
Bn)
to represent a foreign key from the
attributes A1, ..., An of R (the referencing relation)
to S (the referenced relation)):
PREREQUISITE.(CourseNumber) -->
COURSE.(CourseNumber)
PREREQUISITE.(PrerequisiteNumber)
--> COURSE.(CourseNumber)
SECTION.(CourseNumber) -->
COURSE.(CourseNumber)
GRADE_REPORT.(StudentNumber) -->
STUDENT.(StudentNumber)
GRADE_REPORT.(SectionIdentifier)
--> SECTION.(SectionIdentifier)
One possible set of CREATE TABLE
statements to define the database is given below.
CREATE TABLE STUDENT ( Name
VARCHAR(30) NOT NULL,
StudentNumber INTEGER NOT NULL,
Class CHAR NOT NULL,
Major CHAR(4),
PRIMARY KEY (StudentNumber) );
CREATE TABLE COURSE ( CourseName
VARCHAR(30) NOT NULL,
CourseNumber CHAR(8) NOT NULL,
CreditHours INTEGER,
Department CHAR(4),
PRIMARY KEY (CourseNumber),
UNIQUE (CourseName) );
CREATE TABLE PREREQUISITE (
CourseNumber CHAR(8) NOT NULL,
PrerequisiteNumber CHAR(8) NOT NULL,
PRIMARY KEY (CourseNumber,
PrerequisiteNumber),
FOREIGN KEY (CourseNumber) REFERENCES
COURSE (CourseNumber),
FOREIGN KEY (PrerequisiteNumber)
REFERENCES
COURSE (CourseNumber) );
CREATE TABLE SECTION (
SectionIdentifier INTEGER NOT NULL,
CourseNumber CHAR(8) NOT NULL,
Semester VARCHAR(6) NOT NULL,
Year CHAR(4) NOT NULL,
Instructor VARCHAR(15),
PRIMARY KEY (SectionIdentifier),
FOREIGN KEY (CourseNumber) REFERENCES
COURSE (CourseNumber) );
CREATE TABLE GRADE_REPORT (
StudentNumber INTEGER NOT NULL,
SectionIdentifier INTEGER NOT NULL,
Grade CHAR,
PRIMARY KEY (StudentNumber,
SectionIdentifier),
FOREIGN KEY (StudentNumber)
REFERENCES
STUDENT (StudentNumber),
FOREIGN KEY (SectionIdentifier)
REFERENCES
SECTION (SectionIdentifier) );
8. 8 Repeat Exercise 8.7, but use
the AIRLINE schema of Figure 5.8.
Answer:
The following referential integrity
constraints should hold:
FLIGHT_LEG.(FLIGHT_NUMBER) -->
FLIGHT.(NUMBER)
FLIGHT_LEG.(DEPARTURE_AIRPORT_CODE)
--> AIRPORT.(AIRPORT_CODE)
FLIGHT_LEG.(ARRIVAL_AIRPORT_CODE)
--> AIRPORT.(AIRPORT_CODE)
LEG_INSTANCE.(FLIGHT_NUMBER,
LEG_NUMBER) -->
FLIGHT_LEG.(FLIGHT_NUMBER,
LEG_NUMBER)
LEG_INSTANCE.(AIRPLANE_ID) -->
AIRPLANE.(AIRPLANE_ID)
LEG_INSTANCE.(DEPARTURE_AIRPORT_CODE)
--> AIRPORT.(AIRPORT_CODE)
LEG_INSTANCE.(ARRIVAL_AIRPORT_CODE)
--> AIRPORT.(AIRPORT_CODE)
FARES.(FLIGHT_NUMBER) -->
FLIGHT.(NUMBER)
CAN_LAND.(AIRPLANE_TYPE_NAME) -->
AIRPLANE_TYPE.(TYPE_NAME)
CAN_LAND.(AIRPORT_CODE) -->
AIRPORT.(AIRPORT_CODE)
AIRPLANE.(AIRPLANE_TYPE) -->
AIRPLANE_TYPE.(TYPE_NAME)
SEAT_RESERVATION.(FLIGHT_NUMBER,
LEG_NUMBER, DATE) -->
LEG_INSTANCE.(FLIGHT_NUMBER,
LEG_NUMBER, DATE)
One possible set of CREATE TABLE
statements to define the database is given below.
CREATE
NAME VARCHAR(30) NOT NULL,
CITY VARCHAR(30) NOT NULL,
STATE VARCHAR(30),
PRIMARY KEY (AIRPORT_CODE) );
CREATE TABLE FLIGHT ( NUMBER
VARCHAR(6) NOT NULL,
AIRLINE VARCHAR(20) NOT NULL,
WEEKDAYS VARCHAR(10) NOT NULL,
PRIMARY KEY (NUMBER) );
CREATE TABLE FLIGHT_LEG (
FLIGHT_NUMBER VARCHAR(6) NOT NULL,
LEG_NUMBER INTEGER NOT NULL,
DEPARTURE_AIRPORT_CODE CHAR(3) NOT
NULL,
SCHEDULED_DEPARTURE_TIME TIMESTAMP
WITH TIME ZONE,
ARRIVAL_AIRPORT_CODE CHAR(3) NOT NULL,
SCHEDULED_ARRIVAL_TIME TIMESTAMP WITH
TIME ZONE,
PRIMARY KEY (FLIGHT_NUMBER,
LEG_NUMBER),
FOREIGN KEY (FLIGHT_NUMBER)
REFERENCES FLIGHT (NUMBER),
FOREIGN KEY (DEPARTURE_AIRPORT_CODE)
REFERENCES
AIRPORT (AIRPORT_CODE),
FOREIGN KEY (ARRIVAL_AIRPORT_CODE) REFERENCES
AIRPORT (AIRPORT_CODE) );
CREATE TABLE LEG_INSTANCE (
FLIGHT_NUMBER VARCHAR(6) NOT NULL,
LEG_NUMBER INTEGER NOT NULL,
LEG_DATE DATE NOT NULL,
NO_OF_AVAILABLE_SEATS INTEGER,
AIRPLANE_ID INTEGER,
DEPARTURE_AIRPORT_CODE CHAR(3),
DEPARTURE_TIME TIMESTAMP WITH TIME
ZONE,
ARRIVAL_AIRPORT_CODE CHAR(3),
ARRIVAL_TIME TIMESTAMP WITH TIME
ZONE,
PRIMARY KEY (FLIGHT_NUMBER,
LEG_NUMBER, LEG_DATE),
FOREIGN KEY (FLIGHT_NUMBER,
LEG_NUMBER) REFERENCES
FLIGHT_LEG (FLIGHT_NUMBER,
LEG_NUMBER),
FOREIGN KEY (AIRPLANE_ID) REFERENCES
AIRPLANE (AIRPLANE_ID),
FOREIGN KEY (DEPARTURE_AIRPORT_CODE)
REFERENCES
AIRPORT (AIRPORT_CODE),
FOREIGN KEY (ARRIVAL_AIRPORT_CODE)
REFERENCES
AIRPORT (AIRPORT_CODE) );
CREATE TABLE FARES ( FLIGHT_NUMBER
VARCHAR(6) NOT NULL,
FARE_CODE VARCHAR(10) NOT NULL,
AMOUNT DECIMAL(8,2) NOT NULL,
RESTRICTIONS VARCHAR(200),
PRIMARY KEY (FLIGHT_NUMBER,
FARE_CODE),
FOREIGN KEY (FLIGHT_NUMBER)
REFERENCES FLIGHT (NUMBER) );
CREATE TABLE AIRPLANE_TYPE (
TYPE_NAME VARCHAR(20) NOT NULL,
MAX_SEATS INTEGER NOT NULL,
COMPANY VARCHAR(15) NOT NULL,
PRIMARY KEY (TYPE_NAME) );
CREATE TABLE CAN_LAND (
AIRPLANE_TYPE_NAME VARCHAR(20) NOT NULL,
AIRPORT_CODE CHAR(3) NOT NULL,
PRIMARY KEY (AIRPLANE_TYPE_NAME,
AIRPORT_CODE),
FOREIGN KEY (AIRPLANE_TYPE_NAME)
REFERENCES
AIRPLANE_TYPE (TYPE_NAME),
FOREIGN KEY (AIRPORT_CODE) REFERENCES
AIRPORT (AIRPORT_CODE) );
CREATE TABLE AIRPLANE ( AIRPLANE_ID
INTEGER NOT NULL,
TOTAL_NUMBER_OF_SEATS INTEGER NOT
NULL,
AIRPLANE_TYPE VARCHAR(20) NOT NULL,
PRIMARY KEY (AIRPLANE_ID),
FOREIGN KEY (AIRPLANE_TYPE)
REFERENCES AIRPLANE_TYPE (TYPE_NAME) );
CREATE TABLE SEAT_RESERVATION (
FLIGHT_NUMBER VARCHAR(6) NOT NULL,
LEG_NUMBER INTEGER NOT NULL,
LEG_DATE DATE NOT NULL,
SEAT_NUMBER VARCHAR(4),
CUSTOMER_NAME VARCHAR(30) NOT NULL,
CUSTOMER_PHONE CHAR(12),
PRIMARY KEY (FLIGHT_NUMBER,
LEG_NUMBER, LEG_DATE, SEAT_NUMBER),
FOREIGN KEY (FLIGHT_NUMBER,
LEG_NUMBER, LEG_DATE) REFERENCES
LEG_INSTANCE (FLIGHT_NUMBER,
LEG_NUMBER, LEG_DATE) );
8.9 Consider the LIBRARY relational
database schema of Figure 6.12. Choose
the appropriate action (reject,
cascade, set to null, set to default) for each
referential integrity constraint,
both for DELETE of a referenced tuple, and for UPDATE of a primary key attribute value in a referenced
tuple. Justify your choices.
Answer:
Below are possible choices. In
general, if it is not clear which action to choose, REJECT
should be chosen, since it will not
permit automatic changes to happen (by update
propagation) that may be unintended.
BOOK_AUTHORS.(BookId) -->
BOOK.(BookId)
CASCADE on both DELETE or UPDATE
(since this corresponds to a multi-valued attribute
of BOOK (see the solution to
Exercise 6.27); hence, if a BOOK is deleted, or the value of
its BookId is updated (changed), the
deletion or change is automatically propagated to the
referencing BOOK_AUTHORS tuples)
BOOK.(PublisherName) -->
PUBLISHER.(Name)
REJECT on DELETE (we should not
delete a PUBLISHER tuple which has existing BOOK
tuples that reference the PUBLISHER)
CASCADE on UPDATE (if a PUBLISHER's
Name is updated, the change should be propagated automatically to all
referencing BOOK tuples)
BOOK_LOANS.(BookId) -->
BOOK.(BookId)
CASCADE on both DELETE or UPDATE (if
a BOOK is deleted, or the value of its BookId is
updated (changed), the deletion or
change is automatically propagated to the referencing
BOOK_LOANS tuples) (Note: One could
also choose REJECT on DELETE)
BOOK_COPIES.(BookId) -->
BOOK.(BookId)
CASCADE on both DELETE or UPDATE (if
a BOOK is deleted, or the value of its BookId is
updated (changed), the deletion or
change is automatically propagated to the referencing
BOOK_COPIES tuples)
BOOK_LOANS.(CardNo) -->
BORROWER.(CardNo)
CASCADE on both DELETE or UPDATE (if
a BORROWER tuple is deleted, or the value of its CardNo is updated (changed),
the deletion or change is automatically propagated to the
referencing BOOK_LOANS tuples)
(Note: One could also choose REJECT on DELETE, with
the idea that if a BORROWER is
deleted, it is necessary first to make a printout of all
BOOK_LOANS outstanding before
deleting the BORROWER; in this case, the tuples in
BOOK_LOANS that reference the
BORROWER being deleted would first be explicitly
deleted after making the printout,
and before the BORROWER is deleted)
BOOK_COPIES.(BranchId) -->
LIBRARY_BRANCH.(BranchId)
CASCADE on both DELETE or UPDATE (if
a LIBRARY_BRANCH is deleted, or the value of
its BranchId is updated (changed),
the deletion or change is automatically propagated to
the referencing BOOK_COPIES tuples)
(Note: One could also choose REJECT on DELETE)
BOOK_LOANS.(BranchId) --> LIBRARY_BRANCH.(BranchId)
CASCADE on both DELETE or UPDATE (if
a LIBRARY_BRANCH is deleted, or the value of
its BranchId is updated (changed),
the deletion or change is automatically
propagated to the referencing
BOOK_LOANS tuples) (Note: One could also choose
REJECT on DELETE)
8.10 Write appropriate SQL DDL
statements for declaring the LIBRARY relational database
schema of Figure 76.12. Use the
referential action chosen in Exercise 8.9.
Answer: One possible set of CREATE
TABLE statements is given below:
CREATE TABLE BOOK ( BookId CHAR(20)
NOT NULL,
Title VARCHAR(30) NOT NULL,
PublisherName VARCHAR(20),
PRIMARY KEY (BookId),
FOREIGN KEY (PublisherName)
REFERENCES PUBLISHER (Name) ON UPDATE CASCADE );
CREATE TABLE BOOK_AUTHORS ( BookId
CHAR(20) NOT NULL,
AuthorName VARCHAR(30) NOT NULL,
PRIMARY KEY (BookId, AuthorName),
FOREIGN KEY (BookId) REFERENCES BOOK
(BookId)
ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE TABLE PUBLISHER ( Name
VARCHAR(20) NOT NULL,
Address VARCHAR(40) NOT NULL,
Phone CHAR(12),
PRIMARY KEY (Name) );
CREATE TABLE BOOK_COPIES ( BookId
CHAR(20) NOT NULL,
BranchId INTEGER NOT NULL,
No_Of_Copies INTEGER NOT NULL,
PRIMARY KEY (BookId, BranchId),
FOREIGN KEY (BookId) REFERENCES BOOK
(BookId)
ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (BranchId) REFERENCES
BRANCH (BranchId)
ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE TABLE BORROWER ( CardNo
INTEGER NOT NULL,
Name VARCHAR(30) NOT NULL,
Address VARCHAR(40) NOT NULL,
Phone CHAR(12),
PRIMARY KEY (CardNo) );
CREATE TABLE BOOK_LOANS ( CardNo
INTEGER NOT NULL,
BookId CHAR(20) NOT NULL,
BranchId INTEGER NOT NULL,
DateOut DATE NOT NULL,
DueDate DATE NOT NULL,
PRIMARY KEY (CardNo, BookId,
BranchId),
FOREIGN KEY (CardNo) REFERENCES
BORROWER (CardNo)
ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (BranchId) REFERENCES
LIBRARY_BRANCH (BranchId)
ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (BookId) REFERENCES BOOK
(BookId)
ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE TABLE LIBRARY_BRANCH (
BranchId INTEGER NOT NULL,
BranchName VARCHAR(20) NOT NULL,
Address VARCHAR(40) NOT NULL,
PRIMARY KEY (BranchId) );
8.11 Write SQL queries for the
LIBRARY database queries given in Exercise 6.18.
Answer:
Below, we give one possible SQL
query for each request. Other queries are also possible.
(a) How many copies of the book
titled The Lost Tribe are owned by the library branch
whose name is
"Sharpstown"?
SELECT NoOfCopies
FROM ( (BOOK NATURAL JOIN
BOOK_COPIES ) NATURAL JOIN LIBRARY_BRANCH )
WHERE Title='The Lost Tribe' AND
BranchName='Sharpstown'
(b) How many copies of the book
titled The Lost Tribe are owned by each library
branch?
SELECT BranchName, NoOfCopies
FROM ( (BOOK NATURAL JOIN
BOOK_COPIES ) NATURAL JOIN LIBRARY_BRANCH )
WHERE Title='The Lost Tribe'
(c) Retrieve the names of all
borrowers who do not have any books checked out.
SELECT Name
FROM BORROWER B
WHERE NOT EXIST ( SELECT *
FROM BOOK_LOANS L
WHERE B.CardNo = L.CardNo )
(d) For each book that is loaned out
from the "Sharpstown" branch and whose DueDate
is today, retrieve the book title,
the borrower's name, and the borrower's address.
SELECT B.Title, R.Name, R.Address
FROM BOOK B, BORROWER R, BOOK_LOANS
BL, LIBRARY_BRANCH LB
WHERE LB.BranchName='Sharpstown' AND
LB.BranchId=BL.BranchId AND
BL.DueDate='today' AND
BL.CardNo=R.CardNo AND BL.BookId=B.BookId
(e) For each library branch,
retrieve the branch name and the total number of books
loaned out from that branch.
SELECT L.BranchName, COUNT(*)
FROM BOOK_COPIES B, LIBRARY_BRANCH L
WHERE B.BranchId = L.BranchId
GROUP BY L.BranchName
(f) Retrieve the names, addresses,
and number of books checked out for all borrowers
who have more than five books
checked out.
SELECT B.CardNo, B.Name, B.Address,
COUNT(*)
FROM BORROWER B, BOOK_LOANS L
WHERE B.CardNo = L.CardNo
GROUP BY B.CardNo
HAVING COUNT(*) > 5
(g) For each book authored (or
co-authored) by "Stephen King", retrieve the title and
the number of copies owned by the
library branch whose name is "Central".
SELECT TItle, NoOfCopies
FROM ( ( (BOOK_AUTHORS NATURAL JOIN
BOOK) NATURAL JOIN BOOK_COPIES)
NATURAL JOIN LIBRARY_BRANCH)
WHERE Author_Name = 'Stephen King'
and BranchName = 'Central'
8.12 How can the key and foreign key
constraints be enforced by the DBMS? Is the enforcement technique you suggest
difficult to implement? Can the constraint checks be executed in an efficient
manner when updates are applied to the database?
Answer:
One possible technique that is often
used to check efficiently for the key constraint
is to create an index on the
combination of attributes that form each key (primary or
secondary). Before inserting a new
record (tuple), each index is searched to check that
no value currently exists in the
index that matches the key value in the new record. If
this is the case, the record is
inserted successfully.
For checking the foreign key constraint,
an index on the primary key of each
referenced relation will make this
check relatively efficient. Whenever a new record is
inserted in a referencing relation ,
its foreign key value is used to search the index for
the primary key of the referenced
relation, and if the referenced record exists, then the
new record can be successfully
inserted in the referencing relation.
For deletion of a referenced record,
it is useful to have an index on the foreign key
of each referencing relation so as
to be able to determine efficiently whether any records
reference the record being deleted.
If the indexes described above do
not exist, and no alternative access structure (for
example, hashing) is used in their
place, then it is necessary to do linear searches to
check for any of the above
constraints, making the checks quite inefficient.
8.13 Specify the queries of Exercise
6.16 in SQL. Show the result of each query if
applied to the COMPANY database of
Figure 5.6.
Answers:
In SQL, as in most languages, it is
possible to specify the same query in
multiple ways. We will give one or
more possible specification for each query.
(a) Retrieve the names of employees
in department 5 who work more than 10 hours per
week on the 'ProductX' project.
SELECT LNAME, FNAME
FROM EMPLOYEE, WORKS_ON, PROJECT
WHERE DNO=5 AND SSN=ESSN AND
PNO=PNUMBER AND PNAME='ProductX' AND HOURS>10
Another possible SQL query uses
nesting as follows:
SELECT LNAME, FNAME
FROM EMPLOYEE
WHERE DNO=5 AND SSN IN ( SELECT ESSN
FROM WORKS_ON
WHERE HOURS>10 AND PNO IN ( SELECT
PNUMBER
FROM PROJECT
WHERE PNAME='ProductX' ) )
Result:
LNAME FNAME
Smith John
English Joyce
(b) List the names of employees who
have a dependent with the same first name as
themselves.
SELECT LNAME, FNAME
FROM EMPLOYEE, DEPENDENT
WHERE SSN=ESSN AND
FNAME=DEPENDENT_NAME
Another possible SQL query uses
nesting as follows:
SELECT LNAME, FNAME
FROM EMPLOYEE
WHERE EXISTS ( SELECT *
FROM DEPENDENT
WHERE FNAME=DEPENDENT_NAME AND
SSN=ESSN )
Result (empty):
LNAME FNAME
(c) Find the names of employees that
are directly supervised by 'Franklin Wong'.
SELECT E.LNAME, E.FNAME
FROM EMPLOYEE E, EMPLOYEE S
WHERE S.FNAME='
Another possible SQL query uses
nesting as follows:
SELECT LNAME, FNAME
FROM EMPLOYEE
WHERE SUPERSSN IN ( SELECT SSN
FROM EMPLOYEE
WHERE FNAME='Franklin' AND
LNAME='Wong' )
Result:
LNAME FNAME
Smith John
Narayan Ramesh
English Joyce
(d) For each project, list the
project name and the total hours per week (by all
employees) spent on that project.
SELECT PNAME, SUM (HOURS)
FROM PROJECT, WORKS_ON
WHERE PNUMBER=PNO
GROUP BY PNAME
Result:
PNAME SUM(HOURS)
ProductX 52.5
ProductY 37.5
ProductZ 50.0
Computerization 55.0
Reorganization 25.0
Newbenefits 55.0
(e) Retrieve the names of employees
who work on every project.
SELECT LNAME, FNAME
FROM EMPLOYEE
WHERE NOT EXISTS ( SELECT PNUMBER
FROM PROJECT
WHERE NOT EXISTS ( SELECT *
FROM WORKS_ON
WHERE PNUMBER=PNO AND ESSN=SSN ) )
Result (empty):
LNAME FNAME
(f) Retrieve the names of employees
who do not work on any project.
SELECT LNAME, FNAME
FROM EMPLOYEE
WHERE NOT EXISTS ( SELECT *
FROM WORKS_ON
WHERE ESSN=SSN )
Result (empty):
LNAME FNAME
(g) For each department, retrieve
the department name, and the average salary of
employees working in that
department.
SELECT DNAME, AVG (SALARY)
FROM DEPARTMENT, EMPLOYEE
WHERE DNUMBER=DNO
GROUP BY DNAME
Result:
DNAME AVG(SALARY)
Research 33250
Administration 31000
Headquarters 55000
(h) Retrieve the average salary of
all female employees.
SELECT AVG (SALARY)
FROM EMPLOYEE
WHERE SEX='F'
Result:
AVG(SALARY)
31000
(i) Find the names and addresses of
employees who work on at least one project located
in
SELECT LNAME, FNAME, ADDRESS
FROM EMPLOYEE
WHERE EXISTS ( SELECT *
FROM WORKS_ON, PROJECT
WHERE SSN=ESSN AND PNO=PNUMBER AND
PLOCATION='
AND
NOT EXISTS ( SELECT *
FROM DEPT_LOCATIONS
WHERE DNO=DNUMBER AND DLOCATION='
Result:
LNAME FNAME ADDRESS
Wallace Jennifer 291
(j) List the last names of
department managers who have no dependents.
SELECT LNAME, FNAME
FROM EMPLOYEE
WHERE EXISTS ( SELECT *
FROM DEPARTMENT
WHERE SSN=MGRSSN )
AND
NOT EXISTS ( SELECT *
FROM DEPENDENT
WHERE SSN=ESSN )
Result:
LNAME FNAME
Borg James
8.14 Specify the following
additional queries on the database of Figure 5.5 in SQL. Show
the query results if applied to the
database of Figure 5.6.
(a) For each department whose
average employee salary is more than $30000, retrieve
the department name and the number
of employees working for that department.
(b) Suppose we want the number of
male employees in each department rather than all
employees as in Exercise 8.14(a).
Can we specify this query in SQL? Why or why not?
Answers:
(a) SELECT DNAME, COUNT (*)
FROM DEPARTMENT, EMPLOYEE
WHERE DNUMBER=DNO
GROUP BY DNAME
HAVING AVG (SALARY) > 30000
Result:
DNAME DNUMBER COUNT(*)
Research 5 4
Administration 4 3
Headquarters 1 1
(b) The query may still be specified
in SQL by using a nested query as follows (not all
implementations may support this
type of query):
SELECT DNAME, COUNT (*)
FROM DEPARTMENT, EMPLOYEE
WHERE DNUMBER=DNO AND SEX='M' AND DNO
IN ( SELECT DNO
FROM EMPLOYEE
GROUP BY DNO
HAVING AVG (SALARY) > 30000 )
GROUP BY DNAME
Result:
DNAME DNUMBER COUNT(*)
Research 5 3
Administration 4 1
Headquarters 1 1
8.15 Specify the updates of Exercise
5.10 using the SQL update commands.
Answers:
Below, we show how each of the
updates may be specified in SQL. Notice that some of
these updates violate integrity
constraints as discussed in the solution to Exercise 5.10,
and hence should be rejected if
executed on the database of Figure 5.6.
(a) Insert < 'Robert', 'F',
'Scott', '943775543', '21-JUN-42',
INSERT INTO EMPLOYEE
VALUES ('Robert', 'F', 'Scott',
'943775543', '21-JUN-42', '2365
M, 58000, '888665555', 1)
(b) Insert < 'ProductA', 4,
'Bellaire', 2 > into PROJECT.
INSERT INTO PROJECT
VALUES ('ProductA', 4, 'Bellaire', 2)
(c) Insert < 'Production', 4,
'943775543', '01-OCT-88' > into DEPARTMENT.
INSERT INTO DEPARTMENT
VALUES ('Production', 4, '943775543',
'01-OCT-88')
(d) Insert < '677678989', null,
'40.0' > into WORKS_ON.
INSERT INTO WORKS_ON
VALUES ('677678989', NULL, '40.0')
(e) Insert < '453453453', 'John',
M, '12-DEC-60', 'SPOUSE' > into DEPENDENT.
INSERT INTO DEPENDENT
VALUES ('453453453', 'John', M,
'12-DEC-60', 'SPOUSE')
(f) Delete the WORKS_ON tuples with
ESSN= '333445555'.
DELETE FROM WORKS_ON
WHERE ESSN= '333445555'
(g) Delete the EMPLOYEE tuple with
SSN= '987654321'.
DELETE FROM EMPLOYEE
WHERE SSN= '987654321'
(h) Delete the PROJECT tuple with
PNAME= 'ProductX'.
DELETE FROM PROJECT
WHERE PNAME= 'ProductX'
(i) Modify the MGRSSN and
MGRSTARTDATE of the DEPARTMENT tuple with DNUMBER=
5 to '123456789' and '01-OCT-88',
respectively.
UPDATE DEPARTMENT
SET MGRSSN = '123456789',
MGRSTARTDATE = '01-OCT-88'
WHERE DNUMBER= 5
(j) Modify the SUPERSSN attribute of
the EMPLOYEE tuple with SSN= '999887777' to
'943775543'.
UPDATE EMPLOYEE
SET SUPERSSN = '943775543'
WHERE SSN= '999887777'
(k) Modify the HOURS attribute of
the WORKS_ON tuple with ESSN= '999887777' and
PNO= 10 to '5.0'.
UPDATE WORKS_ON
SET HOURS = '5.0'
WHERE ESSN= '999887777' AND PNO= 10
8.16 Specify the following queries
in SQL on the database schema of Figure 1.2.
(a) Retrieve the names of all senior
students majoring in 'COSC' (computer science).
(b) Retrieve the names of all
courses taught by professor King in 85 and 86.
(c) For each section taught by
professor King, retrieve the course number, semester,
year, and number of students who
took the section.
(d) Retrieve the name and transcript
of each senior student (Class=5) majoring in
COSC. Transcript includes course
name, course number, credit hours, semester, year,
and grade for each course completed
by the student.
(e) Retrieve the names and major
departments of all straight A students (students who
have a grade of A in all their
courses).
(f) Retrieve the names and major
departments of all students who do not have any grade
of A in any of their courses.
Answers:
(a) SELECT Name
FROM STUDENT
WHERE Major='COSC'
(b) SELECT CourseName
FROM COURSE, SECTION
WHERE
COURSE.CourseNumber=SECTION.CourseNumber AND Instructor='King'
AND (Year='85' OR Year='86')
Another possible SQL query uses
nesting as follows:
SELECT CourseName
FROM COURSE
WHERE CourseNumber IN ( SELECT
CourseNumber
FROM SECTION
WHERE Instructor='King' AND
(Year='85' OR Year='86') )
(c) SELECT CourseNumber, Semester, Year, COUNT(*)
FROM SECTION, GRADE_REPORT
WHERE Instructor='King' AND
SECTION.SectionIdentifier=GRADE_REPORT.SectionIdentifier
GROUP BY CourseNumber, Semester, Year
(d) SELECT Name, CourseName, C.CourseNumber, CreditHours,
Semester, Year, Grade
FROM
WHERE Class=5 AND Major='COSC' AND
ST.StudentNumber=G.StudentNumber AND
G.SectionIdentifier=S.SectionIdentifier
AND S.CourseNumber=C.CourseNumber
(e) SELECT Name, Major
FROM STUDENT
WHERE NOT EXISTS ( SELECT *
FROM GRADE_REPORT
WHERE StudentNumber=
STUDENT.StudentNumber AND NOT(Grade='A'))
(f) SELECT Name, Major
FROM STUDENT
WHERE NOT EXISTS ( SELECT *
FROM GRADE_REPORT
WHERE StudentNumber=
STUDENT.StudentNumber AND Grade='A' )
8.17 Write SQL update statements to
do the following on the database schema shown in
Figure 1.2.
(a) Insert a new student
<'Johnson', 25, 1, 'MATH'> in the database.
(b) Change the class of student
'Smith' to 2.
(c) Insert a new course
<'Knowledge Engineering','COSC4390', 3,'COSC'>.
(d) Delete the record for the
student whose name is 'Smith' and student number is 17.
Answers:
(a) INSERT INTO STUDENT
VALUES ('Johnson', 25, 1, 'MATH')
(b) UPDATE STUDENT
SET CLASS = 2
WHERE Name='Smith'
(c) INSERT INTO COURSE
VALUES ('Knowledge Engineering','COSC4390',
3,'COSC')
(d) DELETE FROM STUDENT
WHERE Name='Smith' AND
StudentNumber=17
8.18 no answer provided