You are on page 1of 6

CIS 331 HOMEWORK 2 SOLUTIONS Section 12

Problem 1

All questions in this problem are based on the data shown in Figure R5.1. This database table is
named EMP_1. The table structure is summarized in Table R5.1. Have in mind that this table is
in relation with another table JOBS, which primary key is JOB_CODE.
FIGURE R5.1 The Contents of the EMP_1 Table

Table R5.1 The EMP_1 Table Structure Summary


Attribute (Field) Name Data Declaration
EMP_NUM CHAR(3)
EMP_LNAME VARCHAR(15)
EMP_FNAME VARCHAR(15)
EMP_INITIAL CHAR(1)
EMP_HIREDATE DATE
JOB_CODE CHAR(3)
Given this information, answer the following questions:

1. Write the SQL code that will create the table structure. Pay particular attention to referential
and entity integrities. (9p)

Since the EMP_NUM is a primary key, it is best to declare it NOT NULL. In fact,
attributes are usually declared NOT NULL for efficiency reasons, unless there is reason
to believe that the attribute is expected to have nulls occasionally. (For example, not
everyone has a middle initial, nor does everyone necessarily have a job code
assignment.) Also, to enforce referential and entity integrity, you should make use of the
primary and foreign key declarations shown in the following sequence. (We're assuming
that the JOB_CODE is the foreign key to a JOB table.)

CREATE TABLE EMP_1 (


EMP_NUM CHAR(3) NOT NULL,
EMP_LNAME CHAR(15 NOT NULL,
EMP_FNAME CHAR(15) NOT NULL,
EMP_INITIAL CHAR(1),
EMP_HIREDATE DATE NOT NULL,
JOB_CODE CHAR(3),

PRIMARY KEY (EMP_NUM),


FOREIGN KEY (JOB_CODE) REFERENCES JOB);

Naturally, if your software's SQL does not allow such enhancements, delete the NOT
NULL and primary key and foreign key references.

2. Having created the table structure in question 1, write the SQL code that will enter the first
data row into the EMP_l table. (7p)

INSERT INTO EMP_1


VALUES ('101', 'News', 'John', 'G', '11/8/92', '502');

3. Assuming that the remaining data have been entered, write the SQL code that will list all
attributes for a job code of 502. (7p)

SELECT *
FROM EMP_1
WHERE JOB_CODE = '502';

4. Write the SQL code that will save the EMP_l table after all the tuples have been inserted.
(7p)

COMMIT EMP_1;

5. Write the SQL code to change the job code to 501 for the person whose personnel number is
106. After you have completed the task, examine the results, and then reset the job code to its
original value. (7p)

First make the change:

UPDATE EMP_1
SET JOB_CODE = '501'
WHERE EMP_NUM = '106';

Next, examine the results with the command

SELECT *
FROM EMP_1
WHERE EMP_NUM = '106';

Finally, reset the job code to its original value:

UPDATE EMP_1
SET JOB_CODE = '500'
WHERE EMP_NUM = '106';
You may also reset the attribute values to their original state with the ROLLBACK
command, assuming that the original database table values had been saved to disk with
COMMIT.

6. Write the SQL code to delete the row for the person named William Smithfield, who was
hired on 06/23/90 and whose job code classification is 500. Assume that the personnel
number is not known (Hint: Use logical operators to include all the information given in this
problem.) (7p)

DELETE FROM EMP_1


WHERE EMP_LNAME = 'Smithfield' AND
EMP_FNAME = 'William' AND
EMP_INITIAL = '' AND
EMP_HIREDATE = '6/23/90' AND
JOB_CODE = '500';

Note: Because Mr. Smithfield does not have a middle initial,


the EMP_INITIAL is null. Because a null is not the same thing
as a blank, the condition EMP_INITIAL = '' uses two
apostrophes without a blank space between them. In other
words, the '' represents two apostrophes, rather than a single
quotation symbol!

7. Create a copy of EMP_1, name it EMP_2, then add the attributes EMP_PCT and
PROJ_NUM to its structure. The EMP_PCT is the bonus percentage to be paid to each
employee. The new attribute characteristics are shown next:
EMP_PCT NUMBER(4,2)
PROJ_NUM CHAR(3)
(HINT: alter the table). (7p)

INSERT INTO EMP_2 (EMP_NUM,


EMP_LNAME,
EMP_FNAME,
EMP_INITIAL,
EMP_HIREDATE,
JOB_CODE)
SELECT *
FROM EMP_1;

ALTER TABLE EMP_2


ADD (EMP_PCT DECIMAL(4,2),
PROJ_NUM CHAR(3));
Problem 2

Consider the LIBRARY relational schema shown at Figure bellow, which is used to keep track of
books, borrowers and book loans. Referential integrity constraints are shown in directed arcs (e.g.
table BOOK has a foreign key PublisherName that points to the table PUBLISHER). Primary
keys are underlined (e.g. BOOK_LOANS has a composity key consisting of three attributes:
BookID, BranchId and CardNo). As we can see, each author may be an author of several books,
each book may have several copies, book is determined by its BookId, so that is possible to exist
two books of the same title but different BookIds. If a borrower has borrowed a book and did not
return it, the data about that are maintained in BOOK_LOANS table. However, when the book is
returned, the corresponding record in BOOK_LOANS is deleted.

Your task is to write SQL expressions for the following queries:

a) How many copies of the book titled ‘Titanic’ are owned by the library branch whose
name is ‘Cottman’? (HINT: In this and some of the following queries, you should
perform join on multiple tables). (7p)

SELECT SUM(No_Of_Copies)
FROM BOOK B, BOOK_COPIES C, LIBRARY_BRANCH L
WHERE B.BookId=C.BookId
AND C.BranchId=L.BranchId
AND B.Title=’Titanic’
AND L.Branch=’Cottman’;

b) How many copies of the book titled ‘Titanic’ are owned by each library branch? (HINT:
it is possible to exist two books of the same title but different BookIds). (7p)

SELECT L.Name SUM(No_Of_Copies)


FROM BOOK B, BOOK_COPIES C, LIBRARY_BRANCH L
WHERE B.BookId=C.BookId
AND C.BranchId=L.BranchId
AND B.Title=’Titanic’
GROUP BY LBranchName;

c) Retrieve the names of all the borrowers who do not have any book checked out. (HINT:
first, create view containing the result of an outer join). (7p)

CREAT VIEW PROBLEM_C


AS SELECT *
FROM BOOK_LOANS L, BORROWER B
WHERE L.CardNo(+)=B.CardNo;

SELECT Name
FROM PROBLEM_C
WHERE BOOK_LOANS.CardNo IS NULL;

d) For each book that is loaned from the ‘Cottman’ branch and whose DueDate is
6/21/2002, retrieve the book title, the borrower’s name and the borrower’s address. (7p)

SELECT BOOK.Title, BORROWER.Name, BORROWER.Address


FROM BOOK, BOOK_LOANS, BORROWER, LIBRARY_BRANCH
WHERE BOOK_LOANS.BookId= BOOK.BookId
AND BOOK_LOANS.CardNo=BORROWER.CardNo
AND BOOK_LOANS.BranchId=LIBRARY_BRANCH.BranchId
AND BOOK_LOANS.DueDate=’6’21’02’
AND LIBRARY_BRANCH.BranchName=’Cottman’;

e) For each library branch, retrieve the branch name and the total number of books loaned
out from that branch. (7p)

SELECT LIBRARY_BRANCH.BranchName, COUNT(*)


FROM LIBRARY_BRANCH, BOOK_LOANS
WHERE LIBRARY_BRANCH.BranchId=BOOK_LOANS.BranchId
GROUP BY LIBRARY_BRANCH.BranchName;

f) Retrieve the names, addresses, and number of books checked out for all borrowers who
have more than five books checked out. (HINT: Use HAVING) (7p)

SELECT B.CardNo, B.Name, B.Address, B.Phone, COUNT(*)


FROM BOOK_LOANS L BORROWER B
WHERE L.CardNo=B.CardNo
GROUP BY B.CardNo
HAVING COUNT(*) >5;

g) For each book authored by ‘Ivo Andric’ retrieve the title and the number of copies owned
by the library branch whose name is ‘Central’. (7p)

SELECT Title, No_Of_Copies


FROM BOOK_AUTHORS A, BOOK B, COOK_COPIES C, LIBRARY BRANCH L
WHERE A.BookId=B.BookId
AND C.BookId=B.BookId
AND C.BranchId=L.BranchId
AND AuthorName=’Ivo Andric’
AND BranchName=’Central’;