dbms cases
dbms cases
The University consists of a number of faculties, such as the Art Faculty, the
Science Faculty, and so on. Each faculty has a name, dean and building. A faculty may be
divided into a number of schools, for example, the Science Faculty has a School of
Physics and a School of Chemistry. Each school belongs to one faculty only and is
located on just one campus, but one campus maybe the location of many schools.
Every school has name and an building assigned to. Each school offers different
programmes and each programme can be offered by only one school. Each programme
has a unique code, title, level and duration. Each programme comprises several courses,
different programmes have different courses. Each course has a unique code and course
title. Some courses may have one or more prerequisite courses and one course can be the
prerequisite course of some other courses.
The school employs lecturers to teach the students. A lecturer is allowed to work
for one school only. Each lecturer is assigned an ID which is unique across the whole
university. The system keeps the lecturer’s name, title and the office room. A supervisor
maybe in charge of several lecturers, but a lecturer, however reports to only one
supervisor. A lecturer can teach many different courses. A course may also have been
taught by many different lecturers.
Sample Queries:
Query 1: List all the schools are located in 'Pune Campus', and sort them by school
name.
Query 3: Give all the names of the lecturers who are the members of the committee and
sort by their name.
Query 4: List all supervisor's name and the name of the lecturer they manage. Please sort
by supervisor name and lecturer name.
Query 5: Give all the lecturers who are not the member of the committee.
SELECT STFID AS STAFF_ID
FROM LECTURER
WHERE STFID NOT IN (SELECT DISTINCT STFID FROM COMMITTEE_LECTURER)
Query 7: Give all the lecturers with the courses they are teaching. Sort by lecturer name.
SELECT L.LECTNM AS LECTURER_NAME,C.CRSETITL AS COURSE_TITLE
FROM LECTURER_COURSE LC
INNER JOIN LECTURER L ON LC.STFID = L.STFID
INNER JOIN COURSE C ON LC.CRSECD = C.CRSECD
ORDER BY L.LECTNM
Query 8: Give all the course titles and their corresponding prerequisite course titles.
SELECT C1.CRSETITL AS COURSE_TITLE,C2.CRSETITL AS PRE_COURSE_TITLE
FROM PRE_COURSE PC
INNER JOIN COURSE C1 ON PC.CRSECD = C1.CRSECD
INNER JOIN COURSE C2 ON PC.PRECRSECD = C2.CRSECD
Query 9: Give the top 5 courses which have more students involved.
SELECT C.CRSECD AS COURSE_CODE,COUNT(SS.STUID) AS NUMBER_OF_STUDENTS
FROM COURSE_STUDENT SS
LEFT JOIN COURSE S ON SS.SUBJCD = S.SUBJCD
LEFT JOIN COURSE C ON S.CRSECD = C.CRSECD
GROUP BY C.CRSECD
ORDER BY NUMBER_OF_STUDENTS DESC
FETCH FIRST 5 ROWS ONLY
Query 10: Give any of the prerequisite courses was not took by any of the students who
enrolled into the university in 2010, and were taking the courses in 2011.
Query 11: Write a cursor to display school names from ‘PUNE Campus’ order by school
name.
EXEC SQL DECLARE cur1 CURSOR FOR
SELECT SCHLNM AS SCHOOL_NAME
FROM SCHOOL
WHERE CMPSNM = 'PUNE Campus'
ORDER BY SCHLNM;
sqlerr("OPEN cur1");
DBMS Case Study
Case Description: There are 6 different airlines in 6 different countries: Canada – AirCan,
USA - USAir, UK - BritAir, France - AirFrance, Germany - LuftAir, Italy - ItalAir. Their
flights involve the following 12 cities: Toronto and Montreal in Canada, New York and
Chicago in US, London and Edinburgh in UK, Paris and Nice in France, Bonn and Berlin in
Germany, Rome and Naples in Italy. In each of the 12 cities, there is a (single) booking
office. You are going to design a central air-reservation database to be used by all booking
offices.
The flight has a unique flight number, air line code, business class indicator,
smoking allowed indicator. Flight availability has flight number, date + time of departure,
number of total seats available in business class, number of booked seats in business
class, number of total seats available in economy class, and number of booked seats in
economy class.
The customers may come from any country, not just the 6 above, and from any
province/state, and from any city. Customer has first & last name, mailing address, zero
or more phone numbers, zero or more fax numbers, and zero or more email addresses.
Mailing address has street, city, province or state, postal code and country. Phone/fax
number has country code, area code and local number. Email address has only one string,
and no structure is assumed. A customer can book one or more flights. Two or more
customers may have same mailing address and/or same phone number(s) and/or same fax
number(s). But the email address is unique for each customer. First and last names do not
have to be unique.
Booking has an unique booking number, booking city, booking date, flight
number, date + time of departure (in local time, and time is always in hours and minutes),
date + time of arrival (in local time), class indicator, total price (airport tax in origin +
airport tax in destination + flight price – in local currency. The flight price for business
class is 1.5 times of the listed flight price), status indicator (three types: booked. Canceled
– the customer canceled the booking, scratched – the customer had not paid in full 30
days prior to the departure), customer who is responsible for payment, amount-paid-so far
(in local currency), outstanding balance (in local currency), the first & last names to be
printed on the ticket. The airport taxes must be stored in local currencies (i.e. Canadian
dollars, US dollars, British Pounds, French francs, German marks, and Italian Liras).
Since the exchange rates change daily, they also must be stored for calculations of all
prices involved.
Though France, Germany, and Italy have had a common currency for a while, we
used the names of their original currencies to involve in these exercise currency exchange
rates and their changes.
Logical Model:
Table Schema:
CREATE TABLE CUSTOMER (
CUSTID INT NOT NULL,
FNAME VARCHAR(20) NOT NULL,
LNAME VARCHAR(20) NOT NULL,
STREET VARCHAR(50) NOT NULL,
CITY VARCHAR(30) NOT NULL,
PROVINCE VARCHAR(30) NOT NULL,
COUNTRY VARCHAR(30) NOT NULL,
POSTCODE VARCHAR(20) NOT NULL,
PRIMARY KEY (CUSTID)
)
CREATE TABLE PHONE (
PCRTYCODE CHAR(2) NOT NULL,
PAREACODE CHAR(3) NOT NULL,
PNUMBER CHAR(7) NOT NULL,
CUSTID INT NOT NULL,
PRIMARY KEY (CUSTID, PCRTYCODE, PAREACODE, PNUMBER),
FOREIGN KEY (CUSTID) REFERENCES CUSTOMER (CUSTID)
)
CREATE TABLE FAX (
FAREACODE CHAR(3) NOT NULL,
FCTRYCODE CHAR(2) NOT NULL,
FNUMBER CHAR(7) NOT NULL,
CUSTID INT NOT NULL,
PRIMARY KEY (CUSTID, FCTRYCODE, FAREACODE, FNUMBER),
FOREIGN KEY (CUSTID) REFERENCES CUSTOMER (CUSTID)
)
CREATE TABLE EMAIL (
EMAIL VARCHAR(50) NOT NULL,
CUSTID INT NOT NULL,
PRIMARY KEY (CUSTID, EMAIL),
UNIQUE (EMAIL),
FOREIGN KEY (CUSTID) REFERENCES CUSTOMER (CUSTID)
)
CREATE TABLE COUNTRY (
CTRYCD CHAR(2) NOT NULL,
CTRYNM VARCHAR(30),
PRIMARY KEY (CTRYCD)
)
CREATE TABLE AIRLINE (
AIRLINECD VARCHAR(10) NOT NULL,
CTRYCD CHAR(2) NOT NULL,
PRIMARY KEY (AIRLINECD),
FOREIGN KEY (CTRYCD) REFERENCES COUNTRY (CTRYCD)
)
CREATE TABLE FLIGHT (
FNO VARCHAR(10) NOT NULL,
SMALLOW CHAR(1) NOT NULL,
BCAVL CHAR(1),
AIRLINECD VARCHAR(10) NOT NULL,
PRIMARY KEY (FNO),
FOREIGN KEY (AIRLINECD) REFERENCES AIRLINE (AIRLINECD)
)
CREATE TABLE CURRENCY (
FCURR CHAR(3) NOT NULL,
TCURR CHAR(3) NOT NULL,
EXCHRATE DECIMAL(8, 4) NOT NULL,
PRIMARY KEY (FCURR, TCURR)
)
CREATE TABLE CITY (
CITYNM VARCHAR(30),
CITYID INT NOT NULL,
CTRYCD CHAR(2) NOT NULL,
PRIMARY KEY (CITYID),
FOREIGN KEY (CTRYCD) REFERENCES COUNTRY (CTRYCD)
)
CREATE TABLE AIRPORT (
CITYID INT NOT NULL,
AIRPORTCD CHAR(3) NOT NULL,
AIRPORTNM VARCHAR(50),
AIRPORTTAX DECIMAL(6, 2) NOT NULL,
PRIMARY KEY (AIRPORTCD),
FOREIGN KEY (CITYID) REFERENCES CITY (CITYID)
)
CREATE TABLE CITY_CURRENCY (
CITYID INT NOT NULL,
FCURR CHAR(3) NOT NULL,
TCURR CHAR(3) NOT NULL,
PRIMARY KEY (CITYID,FCURR,TCURR),
FOREIGN KEY (CITYID) REFERENCES CITY (CITYID),
FOREIGN KEY (FCURR,TCURR) REFERENCES CURRENCY
(FCURR,TCURR)
)
CREATE TABLE FLIGHT_AVAILABILITY (
FLEN VARCHAR(30) NOT NULL,
DEPTTIME VARCHAR(30) NOT NULL,
ARRTIME VARCHAR(30) NOT NULL,
FNO VARCHAR(10) NOT NULL,
BBUSSEAT INT NOT NULL,
BECOSEAT INT NOT NULL,
TBUSSEAT INT NOT NULL,
TECOSEAT INT NOT NULL,
DEST CHAR(3) NOT NULL,
ORIG CHAR(3) NOT NULL,
PRIMARY KEY (FNO, ORIG, DEST, DEPTTIME, ARRTIME),
FOREIGN KEY (FNO) REFERENCES FLIGHT (FNO),
FOREIGN KEY (DEST) REFERENCES AIRPORT (AIRPORTCD),
FOREIGN KEY (ORIG) REFERENCES AIRPORT (AIRPORTCD)
)
CREATE TABLE CLASS (
CLASSID INT NOT NULL,
CLASS VARCHAR(10),
PRIMARY KEY (CLASSID)
)
CREATE TABLE STATUS (
STATUSID INT NOT NULL,
STATUS VARCHAR(10),
PRIMARY KEY (STATUSID)
)
CREATE TABLE BOOKING (
BKGNO INT NOT NULL,
BKGDATE date NOT NULL,
BAL DECIMAL(8, 2),
TOTPRICE DECIMAL(8, 2),
PAIDAMT DECIMAL(8, 2) NOT NULL,
FPRICE DECIMAL(8, 2) NOT NULL,
FNO VARCHAR(10) NOT NULL,
DEPTTIME VARCHAR(30) NOT NULL,
ARRTIME VARCHAR(30) NOT NULL,
DEST CHAR(3) NOT NULL,
ORIG CHAR(3) NOT NULL,
BKGCITY INT NOT NULL,
CUSTID INT NOT NULL,
PAIDBY INT NOT NULL,
CLASSID INT NOT NULL,
STATUSID INT NOT NULL,
PRIMARY KEY (BKGNO),
FOREIGN KEY (FNO, ORIG, DEST, DEPTTIME, ARRTIME)
REFERENCES
FLIGHT_AVAILABILITY (FNO, ORIG, DEST, DEPTTIME,
ARRTIME),
FOREIGN KEY (BKGCITY) REFERENCES CITY (CITYID),
FOREIGN KEY (CUSTID) REFERENCES CUSTOMER (CUSTID),
FOREIGN KEY (PAIDBY) REFERENCES CUSTOMER (CUSTID),
FOREIGN KEY (CLASSID) REFERENCES CLASS (CLASSID),
FOREIGN KEY (STATUSID) REFERENCES STATUS (STATUSID)
)
Sample Queries:
Query 1: Give all the customers who lives in Canada and sort by customer_id.
SELECT CUSTID AS CUSTOMER_ID
FROM CUSTOMER
WHERE COUNTRY = 'Canada'
ORDER BY CUSTID
Query 3: Display all currency exchange rate is greater than 1. Please sort them by
from_currency and to_currency.
SELECT FCURR AS FROM_CURRENCY,TCURR AS TO_CURRENCY,EXCHRATE AS
EXCHANGE_RATE
FROM CURRENCY
WHERE EXCHRATE > 1
ORDER BY FCURR,TCURR
Query 4: List all the flight availabilities between Toronto (airport code is 'YYZ') and New
York (airport code is 'JFK'). Please display flight_no, origin, destinatin,
depature_time, and arrival_time. Please sort them by flight_no.
Query 5: List all customers who did not place any booking. Please display customer_id
only, and sort records by customer_id.
SELECT CUSTID AS CUSTOMER_ID
FROM CUSTOMER
WHERE CUSTID NOT IN (SELECT DISTINCT CUSTID FROM BOOKING)
ORDER BY CUSTID
Query 6: Display all customer's first_name, last_name, phone_no (format like 416-111-
2222) and email. Please sort them by customer_id.
SELECT C.CUSTID AS CUSTOMER_ID,
C.FNAME AS FIRST_NAME,
C.LNAME AS LAST_NAME,
P.PCRTYCODE||'-'||P.PAREACODE||'-'||P.PNUMBER AS PHONE_NO,
E.EMAIL AS EMAIL
FROM CUSTOMER C
RIGHT JOIN PHONE P ON C.CUSTID = P.CUSTID
RIGHT JOIN EMAIL E ON C.CUSTID = E.CUSTID
ORDER BY C.CUSTID
Query 7: List all canceled bookngs. please display booking_no, customer_id, flight_no,
origin, destination, class, status, and booking_city. Please also sort by
booking_no, customer_id and flight_no.
SELECT BKGNO AS BOOKING_NO,CUSTID AS CUSTOMER_ID,FNO AS FLIGHT_NO,
ORIG AS ORIGIN,DEST AS DESTINATION,C.CLASS AS CLASS,
S.STATUS AS STATUS,CITY.CITYNM AS BOOKING_CITY
FROM BOOKING B
INNER JOIN STATUS S ON B.STATUSID = S.STATUSID
INNER JOIN CLASS C ON B.CLASSID = C.CLASSID
INNER JOIN CITY ON B.BKGCITY = CITY.CITYID
WHERE S.STATUS = 'Canceled' ORDER BY
BKGNO,CUSTID,FNO
Query 8: List total_price, total_payment and total_balance for each city. Please exclude
canceled bookings and sort records by city_name.
SELECT C.CITYNM AS CITY,SUM(TOTPRICE)AS TOTAL_PRICE, SUM(PAIDAMT)
AS TOTAL_PAYMENT,SUM(BAL) AS TOTAL_BALANCE
FROM BOOKING B
INNER JOIN CITY C ON B.BKGCITY = C.CITYID
WHERE STATUSID <> 2
GROUP BY C.CITYNM
ORDER BY C.CITYNM
Query 9: Calculate new total_price for each booking if origin airport tax increase by 0.01
and destination airport tax decrease by 0.005. Please display booking_no,
origin, destination, flight_price, previous_total_price and new_total_price.
SELECT BKGNO AS BOOKING_NO,ORIG AS ORIGIN,
DEST AS DESTINATION,FPRICE AS FLIGHT_PRICE,
TOTPRICE AS PREVIOUS_TOTAL_PRICE, FPRICE*(1+
(O.AIRPORTTAX+0.01)+(D.AIRPORTTAX-0.005)) AS
NEW_TOTAL_PRICE
FROM BOOKING B
INNER JOIN AIRPORT O ON B.ORIG = O.AIRPORTCD
INNER JOIN AIRPORT D ON B.DEST = D.AIRPORTCD
Case Description: - The movies are rented out in stores and there are several stores. Each
store has a unique distributor that supplies the store with tapes. A distributor may supply
more than one store. Each distributor has a name, an address, and a phone number. Each
store has a name, an address, and a phone number. For each employee we must keep the
following information: working store, a name, a supervisor, an address , a phone number,
SIN (social insurance number) and the date when the employee was hired. For each
customer we have to keep the following information: a name, an address, and a phone
number (if any).
For each rental, we must keep track of which employee served the customer,
which movie and which copy (i.e. type) the customer rented, information about payment,
the date and the time of the rental, the status (rented, returned_in_time, returned_late), the
rate (i.e. the price), and if applicable, due date and overdue charges. About the payment
we have to keep which of the employees accepted the payment (does not have to be the
same employee who rented the tape), the type of payment (i.e. cash, check, credit card,
direct debit – for each type you must provide for relevant information to be kept, e.g.
credit card number if credit card is used), the amount of the payment, date + time of the
payment, payment status (completed if cash or the money have been received, approved if
debit or credit card go through, pending if the check has not cleared yet). About each tape
we have to keep information in what condition the tape is and what movie is on the tape.
About each movie we have to keep its title, director’s name, simple description, the name
of a (single) major star, the movie’s rating (use numbers 1-5).
Logical Model
Sample Queries:
Query 1: Give all the customers who lives in Hamilton. Display customer_id
and customer_name.
Query 2: Display the total payment are received by each employee, and sort by empsin.
Query 3: Display the total movies are rented out by each store, and sort by storeid.
Query 4: Display all the tapes are never rented out in every store, and sort by
movieid & tapeid.
SELECT DISTINCT T.MOVIEID,T.TAPEID
FROM TAPE T
LEFT JOIN MOVIE_RENTAL R ON T.MOVIEID=R.MOVIEID AND T.TAPEID=R.TAPEID
WHERE R.MOVIEID IS NULL
ORDER BY T.MOVIEID,T.TAPEID
Query 5: Display all customers who did not rent any movie so far and sort by custid.
SELECT CUSTID,CUSTNM
FROM CUSTOMER
WHERE CUSTID NOT IN (SELECT DISTINCT CUSTID FROM MOVIE_RENTAL)
ORDER BY CUSTID
Query 6: Display the total amount received by different payment type, and sort by
ptdesc.
Query 7. Display the number of movies rented out based on the movie rating, and sort by
rating.
SELECT M.RATING,COUNT(MR.MOVIEID) AS NO_OF_MOVIES
FROM MOVIE_RENTAL MR
INNER JOIN MOVIE M ON MR.MOVIEID = M.MOVIEID
GROUP BY M.RATING
Query 8: Display top 5 customers based on their total payment, and sort their total
payment decreased.
SELECT CUSTID,SUM(AMT) AS TOTAL_AMT
FROM PAYMENT
GROUP BY CUSTID
ORDER BY TOTAL_AMT DESC
Query 9: List all the movies customer rented. Please display the columns: movie_title,
rental_status, rental_rate, rental_employee, the employ accept the payment,
payment_type and payment_status.
SELECT M.MOVIETITL AS MOVIE_TITLE,
RS.RDESC AS RENTAL_STATUS,
MR.RRATE AS RENTAL_RATE,
E1.EMPNM AS RENTAL_EMPLOYEE,
E2.EMPNM AS CASHIER_EMPLOYEE,
PT.PTDESC AS PAYMENT_TYPE,
PS.PDESC AS PAYMENT_STATUS
FROM MOVIE_RENTAL MR
INNER JOIN CUSTOMER C ON MR.CUSTID = C.CUSTID
INNER JOIN MOVIE M ON MR.MOVIEID = M.MOVIEID
INNER JOIN RENTAL_STATUS RS ON MR.RSTATUSID = RS.RSTATUSID
INNER JOIN EMPLOYEE E1 ON MR.EMPSIN = E1.EMPSIN
LEFT JOIN PAYMENT P ON MR.PAYID = P.PAYID LEFT
JOIN EMPLOYEE E2 ON P.EMPSIN = E2.EMPSIN
LEFT JOIN PAYMENT_STATUS PS ON P.PSTATUSID = PS.PSTATUSID
LEFT JOIN PAYMENT_TYPE PT ON P.PTID = PT.PTID
WHERE C.CUSTNM = 'customer1'
Query 10: List all the manager's name and the name of employee they manage.
Please sort by manager sin & employee sin.
SELECT MGR.EMPNM AS MANAGER_NAME,E.EMPNM AS EMPLOYEE_NAME
FROM EMPLOYEE E
INNER JOIN EMPLOYEE MGR ON E.MGRSIN = MGR.EMPSIN
ORDER BY MGR.EMPSIN,E.EMPSIN
Case Description:-Our company does car rental business and has several locations with
different address (address consists of street or rural route with the number, city, province
and postal code). The cars are classified as subcompacts, compacts, sedans, or luxury.
Each car has a particular make, model, year made, and color. Each car has a unique
identification number and a unique license plate.
The cars rented in a particular location may be returned to a different location (so-
called drop off). For every car we keep the odometer reading before it is rented and after
it is returned. Since we trust our customers, we do not record the defect when the car is
rent out and returned back. However, we rent the car with full tank and record the volume
of gas in the tank when the car is returned, but we only indicate if the tank is empty,
quarter full, half full, three quarters full, or full.
We keep track of which day a car was rented, but not of the time, similarly for car
returning. If a customer requests a specific class (say sedan), we may rent the customer a
higher-class car if we do not have the requested class in the stock, but we will price it at
the level the customer requested (so-called upgrade). Each car class has its own pricing,
but all cars in the same class are priced the same. We have rental policies for 1 day, 1
week, 2 weeks, and 1 month. Thus, if a customer rents a car for 8 days, it will be priced
as 1 week + 1 day. The drop-off charge only depends on the class of the rented car, the
location it was rented from and the location it is returned to.
About our customers, we keep their names, addresses, possibly all phone
numbers, and the number of the driver’s license (we assume a unique license per person).
About our employees we keep the same information (we require that all our employees
have a driver’s license). We have several categories of workers, drivers, cleaners, clerks,
and managers. Any of our employees can rent a car from our company for a 50%
discount, if the rental is less than 2 weeks. However, for any longer rental they must pay
90% of the regular price. Every employee works in one location only. We have
headquarters in Hamilton. The people who work there are all classified as managers, one
of them is the president, two of them are the vice-presidents, one for operation, the other
for marketing).
For certain weeks we have promotional rentals that are usually 60% of the regular
price, but may be also of different percentage. They always affect only a single class of
cars – i.e. we may have a promotion for subcompacts, but during that week we do not
have any promotions for compacts, sedans or luxury cars. During some years we can
have many promotions, in some we have none. The promotions cannot be applied to the
employees.
Logical Model
Figure: The Car Rental Logic Model
Table Schema:
Sample Queries
Query 1: Give last name of all customers who are now renting a car from our company.
SELECT LNAME
FROM CUSTOMER, PERSON, RENTAL
WHERE CUSTOMER.DLICENSE=RENTAL.DLICENSE AND CUSTOMER.DLICENSE =
PERSON.DLICENSE AND TO_DATE IS NULL
Query 2: Give make and color of all cars currently rented out.
SELECT MAKE,COLOUR
FROM CAR,RENTAL
WHERE CAR.CARID=RENTAL.CARID AND TO_DATE IS NULL
Query 3: For each completed rental, give the rental price and rental_id.
SELECT SUM(CHARGE), RENTALID
FROM (SELECT RENTALID,AMOUNT*COUNT
FROM RENTALRATE,PRATE
WHERE RENTALRATE.DURATION=PRATE.DURATION
AND RENTALRATE.CLASS=PRATE.CLASS) AS T(RENTALID,CHARGE)
GROUP BY RENTALID
SELECT LNAME
FROM EMPLOYEE, PERSON
WHERE ETYPE='M' AND EMPLOYEE.DLICENSE=PERSON.DLICENSE
Query 6: Give a query that answers the question "Is any of our employee also
our customer"?
SELECT *
FROM EMPLOYEE, CUSTOMER
WHERE EMPLOYEE.DLICENSE=CUSTOMER.DLICENSE
SELECT *
FROM EMPLOYEE, ADDRESS
WHERE IS_PRES='P' AND LOCATION=ADDRESSID AND ADDRESS.IS_HQUARTERS='H'
Query 8: Find rental_id of all shortest (completed) rentals.
SELECT RENTALID
FROM RENTAL
WHERE TO_DATE IS NOT NULL AND (DAYS(TO_DATE)-DAYS(FROM_DATE))
IN (SELECT MIN(DAYS(TO_DATE) - DAYS(FROM_DATE))
FROM RENTAL
WHERE TO_DATE IS NOT NULL)
Query 9: Find the value of the cheapest (completed) rental. We will utilize query 3 as the
inner query.
SELECT MIN(CHARGE)
FROM (SELECT SUM(CHARGE), RENTALID
FROM (SELECT RENTALID,AMOUNT*COUNT
FROM RENTALRATE,PRATE
WHERE RENTALRATE.DURATION=PRATE.DURATION
AND RENTALRATE.CLASS=PRATE.CLASS) AS T(RENTALID,CHARGE)
GROUP BY RENTALID) AS T1(CHARGE,RENTALID)
Query 10: Give makes of the cars that have never been rented.
Each course has a unique designation, title, description, year (in which year of study the
nd
course is to be taken, for instance 2 year course), and classroom. A course can have no
or many tutorial sections, and no or many lab sections. Each course is taught by exactly
one instructor. Each instructor has a unique id, name, departmental affiliation, office
room, phone extension, and a unique email address. Each student has a unique id, name,
and the year of his/her study. A student cannot be an instructor. A course can have zero
or many tutorial sections unique to the course (i.e. tutorial sections are not shared by
different courses). Each tutorial section has exactly one TA assigned. A TA can tutor
more than one tutorial section for the same course, and any number of tutorials for
different courses. A TA cannot be an instructor, however a student can work as a TA (in
that case his/her student id is used as TA id). A course can have zero or many lab sections
unique to the course (i.e. lab sections are not shared by different courses). Each lab
section has exactly one LA assigned. An LA can oversee more than one lab section for
the same course, and any number of labs for different courses. An LA cannot be an
instructor, however a student can work as a LA (in which case his/her student id is used
as the LA id). In fact, a student can work as a TA and an LA simultaneously. Thus, a TA
may or may not be a student, an LA may or may not be a student. A person can work as
both, a TA and a LA. TA has the same attributes as instructor, the same goes for LA.
Each course has zero to many courses designated as its prerequisites and zero to
many courses designated as its anti-requisites. Prerequisite courses are of the same or
lower year, anti-requisite courses are of the same year. In the system we keep information
of what courses a student has taken and what courses the student is registering. All
courses are either Pass or Fail. A student can register a course only if he/she has passed
all the prerequisites and has not passed any or is not registered in any of the anti-
requisites. A student can only register a course of the appropriate year, i.e. a student in
year X of study can only register and take course of year X.
Logical Model
Figure: The Course Registration Logical Model
Table Schema
CREATE TABLE COURSE (
DESIG CHAR(5) NOT NULL,
TITLE CHAR(30) NOT NULL,
DESCR CHAR(150) NOT NULL,
CLASSROOM CHAR(5) NOT NULL,
PRIMARY KEY(DESIG)
)
CREATE TABLE Y1COURSE (
DESIG CHAR(5) NOT NULL,
PRIMARY KEY(DESIG)
)
CREATE TABLE Y2COURSE (
DESIG CHAR(5) NOT NULL,
PRIMARY KEY(DESIG)
)
CREATE TABLE Y3COURSE (
DESIG CHAR(5) NOT NULL,
PRIMARY KEY(DESIG)
)
CREATE TABLE Y4COURSE (
DESIG CHAR(5) NOT NULL,
PRIMARY KEY(DESIG)
)
CREATE TABLE PREREQ11 (
DESIG1 CHAR(5) NOT NULL,
DESIG2 CHAR(5) NOT NULL,
PRIMARY KEY(DESIG1,DESIG2)
)
CREATE TABLE PREREQ12 (
DESIG1 CHAR(5) NOT NULL,
DESIG2 CHAR(5) NOT NULL,
PRIMARY KEY(DESIG1,DESIG2),
FOREIGN KEY (DESIG1) REFERENCES Y1COURSE
(DESIG), FOREIGN KEY (DESIG2) REFERENCES
Y2COURSE (DESIG), CONSTRAINT PREREQ12_C3
CHECK (DESIG1<>DESIG2)
)
CREATE TABLE PREREQ13 (
DESIG1 CHAR(5) NOT NULL,
DESIG2 CHAR(5) NOT NULL,
PRIMARY KEY(DESIG1,DESIG2),
FOREIGN KEY (DESIG1) REFERENCES
Y1COURSE (DESIG), FOREIGN KEY (DESIG2)
REFERENCES Y3COURSE (DESIG), CONSTRAINT
PREREQ13_C3 CHECK (DESIG1<>DESIG2)
)
CREATE TABLE PREREQ14 (
DESIG1 CHAR(5) NOT NULL,
DESIG2 CHAR(5) NOT NULL,
PRIMARY KEY(DESIG1,DESIG2),
FOREIGN KEY (DESIG1) REFERENCES
Y1COURSE (DESIG), FOREIGN KEY (DESIG2)
REFERENCES Y4COURSE (DESIG),
CONSTRAINT PREREQ14_C3 CHECK
(DESIG1<>DESIG2)
)
CREATE TABLE PREREQ22 (
DESIG1 CHAR(5) NOT NULL,
DESIG2 CHAR(5) NOT NULL,
PRIMARY KEY(DESIG1,DESIG2),
FOREIGN KEY (DESIG1) REFERENCES Y2COURSE
(DESIG), FOREIGN KEY (DESIG2) REFERENCES
Y2COURSE (DESIG), CONSTRAINT PREREQ22_C3
CHECK (DESIG1<>DESIG2)
)
CREATE TABLE PREREQ23 (
DESIG1 CHAR(5) NOT NULL,
DESIG2 CHAR(5) NOT NULL,
PRIMARY KEY(DESIG1,DESIG2),
FOREIGN KEY (DESIG1) REFERENCES Y2COURSE
(DESIG), FOREIGN KEY (DESIG2) REFERENCES
Y3COURSE (DESIG), CONSTRAINT PREREQ23_C3
CHECK (DESIG1<>DESIG2)
)
CREATE TABLE PREREQ24 (
DESIG1 CHAR(5) NOT NULL,
DESIG2 CHAR(5) NOT NULL,
PRIMARY KEY(DESIG1,DESIG2),
FOREIGN KEY (DESIG1) REFERENCES Y2COURSE
(DESIG), FOREIGN KEY (DESIG2) REFERENCES
Y4COURSE (DESIG), CONSTRAINT PREREQ24_C3
CHECK (DESIG1<>DESIG2)
)
CREATE TABLE PREREQ33 (
DESIG1 CHAR(5) NOT NULL,
DESIG2 CHAR(5) NOT NULL,
PRIMARY KEY(DESIG1,DESIG2),
FOREIGN KEY (DESIG1) REFERENCES Y3COURSE
(DESIG), FOREIGN KEY (DESIG2) REFERENCES
Y3COURSE (DESIG), CONSTRAINT PREREQ33_C3
CHECK (DESIG1<>DESIG2)
)
CREATE TABLE PREREQ34 (
DESIG1 CHAR(5) NOT NULL,
DESIG2 CHAR(5) NOT NULL,
PRIMARY KEY(DESIG1,DESIG2),
FOREIGN KEY (DESIG1) REFERENCES Y3COURSE
(DESIG), FOREIGN KEY (DESIG2) REFERENCES
Y4COURSE (DESIG), CONSTRAINT PREREQ34_C3
CHECK (DESIG1<>DESIG2)
)
CREATE TABLE PREREQ44 (
DESIG1 CHAR(5) NOT NULL,
DESIG2 CHAR(5) NOT NULL,
PRIMARY KEY(DESIG1,DESIG2),
FOREIGN KEY (DESIG1) REFERENCES Y4COURSE
(DESIG), FOREIGN KEY (DESIG2) REFERENCES
Y4COURSE (DESIG), CONSTRAINT PREREQ44_C3
CHECK (DESIG1<>DESIG2)
)
CREATE TABLE ANTIREQ1 (
DESIG1 CHAR(5) NOT NULL,
DESIG2 CHAR(5) NOT NULL,
PRIMARY KEY(DESIG1,DESIG2),
FOREIGN KEY (DESIG1) REFERENCES Y1COURSE (DESIG), FOREIGN KEY
(DESIG2) REFERENCES Y1COURSE (DESIG), CONSTRAINT ANTIREQ1_C3
CHECK (DESIG1<>DESIG2)
)
CREATE TABLE ANTIREQ2 (
DESIG1 CHAR(5) NOT NULL,
DESIG2 CHAR(5) NOT NULL,
PRIMARY KEY(DESIG1,DESIG2),
FOREIGN KEY (DESIG1) REFERENCES Y2COURSE
(DESIG), FOREIGN KEY (DESIG2) REFERENCES
Y2COURSE (DESIG), CONSTRAINT ANTIREQ2_C3
CHECK (DESIG1<>DESIG2)
)
CREATE TABLE ANTIREQ3 (
DESIG1 CHAR(5) NOT NULL,
DESIG2 CHAR(5) NOT NULL,
PRIMARY KEY(DESIG1,DESIG2),
FOREIGN KEY (DESIG1) REFERENCES Y3COURSE
(DESIG), FOREIGN KEY (DESIG2) REFERENCES
Y3COURSE (DESIG), CONSTRAINT ANTIREQ3_C3
CHECK (DESIG1<>DESIG2)
)
CREATE TABLE ANTIREQ4 (
DESIG1 CHAR(5) NOT NULL,
DESIG2 CHAR(5) NOT NULL,
PRIMARY KEY(DESIG1,DESIG2),
FOREIGN KEY (DESIG1) REFERENCES Y4COURSE
(DESIG), FOREIGN KEY (DESIG2) REFERENCES
Y4COURSE (DESIG), CONSTRAINT ANTIREQ4_C3
CHECK (DESIG1<>DESIG2)
)
CREATE TABLE PERSON (
ID CHAR(7) NOT NULL,
NAME CHAR(20) NOT NULL,
PRIMARY KEY(ID)
)
CREATE TABLE STUDENT (
ID CHAR(7) NOT NULL,
YEAR INTEGER NOT NULL,
PRIMARY KEY(ID),
FOREIGN KEY (ID) REFERENCES PERSON (ID)
)
CREATE TABLE INSTRUCTOR (
ID CHAR(7) NOT NULL,
DEPT CHAR(4) NOT NULL,
ROOM CHAR(5) NOT NULL,
EXTENSION CHAR(5) NOT NULL,
EMAIL CHAR(20) NOT NULL,
PRIMARY KEY(ID),
FOREIGN KEY (ID) REFERENCES PERSON
(ID), CONSTRAINT INSTRUCTOR_C2
UNIQUE (EMAIL)
)
CREATE TABLE STAFF (
ID CHAR(7) NOT NULL,
DEPT CHAR(4) NOT NULL,
ROOM CHAR(5) NOT NULL,
EXTENSION CHAR(5) NOT NULL,EMAIL CHAR(20) NOT NULL,
PRIMARY KEY(ID),
FOREIGN KEY (ID) REFERENCES PERSON
(ID), CONSTRAINT STAFF_C2 UNIQUE
(EMAIL)
)
CREATE TABLE LAB (
DESIG CHAR(5) NOT NULL,
SECTION INTEGER NOT NULL,
LABROOM CHAR(5) NOT NULL,
PRIMARY KEY(DESIG,SECTION),
FOREIGN KEY (DESIG) REFERENCES COURSE (DESIG)
)
CREATE TABLE TUTORIAL (
DESIG CHAR(5) NOT NULL,
SECTION INTEGER NOT NULL,
CLASSROOM CHAR(5) NOT NULL,
PRIMARY KEY(DESIG,SECTION),
FOREIGN KEY (DESIG) REFERENCES COURSE (DESIG)
)
CREATE TABLE TA (
ID CHAR(7) NOT NULL,
PRIMARY KEY(ID),
FOREIGN KEY (ID) REFERENCES STAFF (ID)
)
CREATE TABLE LA (
ID CHAR(7) NOT NULL,
PRIMARY KEY(ID),
FOREIGN KEY (ID) REFERENCES STAFF (ID)
)
CREATE TABLE HASTA (
DESIG CHAR(5) NOT NULL,
SECTION INTEGER NOT NULL,
ID CHAR(7) NOT NULL,
PRIMARY KEY(DESIG,SECTION),
FOREIGN KEY (DESIG,SECTION) REFERENCES TUTORIAL
(DESIG,SECTION), FOREIGN KEY (ID) REFERENCES TA (ID)
)
CREATE TABLE HASLA (
DESIG CHAR(5) NOT NULL,
SECTION INTEGER NOT NULL,
ID CHAR(7) NOT NULL,
PRIMARY KEY(DESIG,SECTION),
FOREIGN KEY (DESIG,SECTION) REFERENCES LAB
(DESIG,SECTION), FOREIGN KEY (ID) REFERENCES LA (ID)
)
CREATE TABLE HASI (
DESIG CHAR(5) NOT NULL,
ID CHAR(7) NOT NULL,
PRIMARY KEY(DESIG),
FOREIGN KEY (DESIG) REFERENCES COURSE
(DESIG), FOREIGN KEY (ID) REFERENCES
INSTRUCTOR (ID)
)
CREATE TABLE L1 (
ID CHAR(7) NOT NULL,
DESIG CHAR(5) NOT NULL,
STATUS CHAR(1) NOT NULL CHECK (STATUS IN
('P','F','R')), PRIMARY KEY(ID,DESIG),
FOREIGN KEY (ID) REFERENCES STUDENT (ID),
FOREIGN KEY (DESIG) REFERENCES Y1COURSE
(DESIG)
)
CREATE TABLE L2 (
ID CHAR(7) NOT NULL,
DESIG CHAR(5) NOT NULL,
STATUS CHAR(1) NOT NULL CHECK (STATUS IN
('P','F','R')), PRIMARY KEY(ID,DESIG),
FOREIGN KEY (ID) REFERENCES STUDENT (ID),
FOREIGN KEY (DESIG) REFERENCES Y2COURSE
(DESIG)
)
CREATE TABLE L3 (
ID CHAR(7) NOT NULL,
DESIG CHAR(5) NOT NULL,
STATUS CHAR(1) NOT NULL CHECK (STATUS IN
('P','F','R')), PRIMARY KEY(ID,DESIG),
FOREIGN KEY (ID) REFERENCES STUDENT (ID),
FOREIGN KEY (DESIG) REFERENCES Y3COURSE
(DESIG)
)
CREATE TABLE L4 (
ID CHAR(7) NOT NULL,
DESIG CHAR(5) NOT NULL,
STATUS CHAR(1) NOT NULL CHECK (STATUS IN
('P','F','R')), PRIMARY KEY(ID,DESIG),
FOREIGN KEY (ID) REFERENCES STUDENT (ID),
FOREIGN KEY (DESIG) REFERENCES Y4COURSE
(DESIG)
)
Sample Queries:
Query 1: List all triples (student name, course designation, status) of courses taken or
registered by students with id '0000041' and '0000042'. status is the status of
each course (i.e. 'P' for passed, 'F' for failed, 'R' for registered).
SELECT NAME,DESIG,STATUS
FROM STUDENT, PERSON,L1
WHERE STUDENT.ID=L1.ID
AND (STUDENT.ID='0000041' OR STUDENT.ID='0000042')
AND STUDENT.ID=PERSON.ID
UNION
SELECT NAME,DESIG,STATUS
FROM STUDENT, PERSON,L2
WHERE STUDENT.ID=L2.ID
AND (STUDENT.ID='0000041' OR STUDENT.ID='0000042')
AND STUDENT.ID=PERSON.ID
SELECT PERSON.NAME
FROM PERSON, STUDENT
WHERE PERSON.ID=STUDENT.ID AND STUDENT.YEAR=1
SELECT PERSON.NAME
FROM PERSON, INSTRUCTOR, HASI, Y1COURSE
WHERE PERSON.ID=INSTRUCTOR.ID
AND HASI.ID=INSTRUCTOR.ID AND HASI.DESIG=Y1COURSE.DESIG
Query 4: List designation of all courses that have tutorials. No designation can repeat.
Query 5: List designation of all courses that have labs with more than 1 section. No
designation can repeat.
Query 6: List names of instructors that teach at least one course with multiple sections
labs. No name can repeat.
Query 7: List names of instructors that teach only courses with single-sections labs or no
labs. No name can repeat.
In our Emergency Room (ER), we have three distinct types of workers: receptionists,
nurses, and doctors. Any of the workers can in fact be a patient. Each person in the
proposed system, be it a patient or a worker has a last, a first, possibly a middle name,
and one or more addresses. An address consists of a country, province, city, street and
street number. Each person can have none or more email addresses, none or more
telephone numbers.
The workers work in ER in shifts. A shift consists of start and end time. The shifts
do not overlap, but they are consecutive, i.e. there is a shift on at any given time and day.
We are assuming that the model we are creating (and eventually the database we will
design) covers some extended period of time. Each worker will thus be assigned to many
shifts in that period. Exactly two receptionists are assigned to each shift, a group of two or
more nurses is assigned to each shift, a group of two or more doctors is assigned to each
shift, one of the doctors assigned to a shift is the shift’s triage doctor.
When a patient comes to ER, it happens during a particular shift. The patient is
admitted by a particular receptionist, is seen by the triage doctor of the shift. The patient
may be send home, prescribed some medication by the triage doctor and send home, or is
staying in ER – in which case the patient is assigned a bed and case doctors (one of the
doctors on each shift best qualified for the particular problem of the patient). Each bed is
supervised by a single nurse during a shift, but a nurse may supervise many beds, or none
at all. The case doctor(s) may prescribe a medication that is administered to the patient by
a single nurse in each shift for the duration of the patient taking the medicine. Each
medication has a name, and for each patient there may be a different dosage and different
number of times a day to take it.
Logical Model
Sample Queries:
Query 1: The query returns an empty set if con1 is satisfied.
Case Description: - Our company arranges rentals of properties owned by both private
and business owners. We assign every property owner a unique owner number for
identification, we record its address (consisting of a street, street number, town or city,
and province), the owner’s name (consisting of first, middle, and last name for a person
or name of a business), and the owners email addresses and the owner phone numbers.
For a business owner, we record the type (description) of its business. Each property is
identified by a unique property number, we record its address and its type. Each property
may be placed in several advertisements. Each such advertisement may be displayed in
many newspapers on several dates. The newspapers are identified by unique names.
The term renter refers to a private person or a business who signed a rental
agreement for a property. Each such rental agreement is identified in our database by a
unique rental number. We record the date of the singing of the rental agreement, the
starting and ending date of the rental agreement. A renter can rent many properties. A
renter, prior to accepting the rental agreement may view the property repeatedly and we
record the date of viewing. For each renter, we record its address, its name, its email
address and phone numbers. Each renter has a unique renter number in our database.
Our agency is organized into branches and every staff member is allocated to
exactly one branch. Each branch has one manager who is a member of the staff. In our
database, we identify the staff by a unique staff number. For each staff member we record
address, name, email address, phone numbers, sex, position, and salary. Each property is
in care of one of our branches. Each renter refers to the branch that is in care of the
property it rents. Each property is overseen by a unique staff member. Each branch has an
address, phone number, and a unique branch number.
Logical Model
Figure : The Property Rental Logical Model
Table Schema
CREATE TABLE BRANCH (
BRANCH_NO CHAR(4) NOT NULL,
STREET_NO CHAR(4) NOT NULL,
STREET CHAR(10) NOT NULL,
CITY CHAR(10) NOT NULL,
PROVINCE CHAR(2) NOT NULL,
POSTAL_CODE CHAR(6) NOT NULL,
MANAGER CHAR(4) NOT NULL,
PRIMARY KEY (BRANCH_NO),
CHECK (PROVINCE IN ('AL','BC','MA','NB','NF','NT','NS',
'NU', 'ON','PE','QB','SA','YU')),
CHECK (('A'<=SUBSTR(POSTAL_CODE,1,1) AND
SUBSTR(POSTAL_CODE,1,1)<='Z') AND
('0'<=SUBSTR(POSTAL_CODE,2,1) AND SUBSTR(POSTAL_CODE,2,1)<='9')
AND
('A'<=SUBSTR(POSTAL_CODE,3,1) AND SUBSTR(POSTAL_CODE,3,1)<='Z')
AND
('0'<=SUBSTR(POSTAL_CODE,4,1) AND SUBSTR(POSTAL_CODE,4,1)<='9')
AND
('A'<=SUBSTR(POSTAL_CODE,5,1) AND SUBSTR(POSTAL_CODE,5,1)<='Z')
AND
('0'<=SUBSTR(POSTAL_CODE,6,1) AND
SUBSTR(POSTAL_CODE,6,1)<='9')),
UNIQUE(MANAGER)
)
CREATE TABLE STAFF (
STAFF_NO CHAR(4) NOT NULL,
LAST_NAME CHAR(20) NOT NULL,
FIRST_NAME CHAR(10) NOT NULL,
MIDDLE_NAME CHAR(10),
STREET_NO CHAR(4) NOT NULL,
STREET CHAR(10) NOT NULL,
CITY CHAR(10) NOT NULL,
PROVINCE CHAR(2) NOT NULL,
POSTAL_CODE CHAR(6) NOT NULL,
SEX CHAR(1) NOT NULL,
SALARY DECIMAL(9,2) NOT NULL,
ALLOCATED_TO CHAR(4) NOT NULL,
PRIMARY KEY (STAFF_NO),
FOREIGN KEY (ALLOCATED_TO) REFERENCES BRANCH,
CHECK (PROVINCE IN ('AL','BC','MA','NB','NF','NT','NS',
'NU','ON','PE','QB','SA','YU')),
CHECK (SEX IN ('F','M','N')),
CHECK (SALARY > 0),
CHECK (('A'<=SUBSTR(POSTAL_CODE,1,1)
AND SUBSTR(POSTAL_CODE,1,1)<='Z')
AND ('0'<=SUBSTR(POSTAL_CODE,2,1)
AND SUBSTR(POSTAL_CODE,2,1)<='9')
AND ('A'<=SUBSTR(POSTAL_CODE,3,1)
AND SUBSTR(POSTAL_CODE,3,1)<='Z')
AND ('0'<=SUBSTR(POSTAL_CODE,4,1)
AND SUBSTR(POSTAL_CODE,4,1)<='9')
AND ('A'<=SUBSTR(POSTAL_CODE,5,1)
AND SUBSTR(POSTAL_CODE,5,1)<='Z')
AND ('0'<=SUBSTR(POSTAL_CODE,6,1)
AND SUBSTR(POSTAL_CODE,6,1)<='9'))
)
CREATE TABLE OWNER (
OWNER_NO CHAR(4) NOT NULL,
NAME CHAR(20) NOT NULL,
FIRST_NAME CHAR(10),
MIDDLE_NAME CHAR(10),
STREET_NO CHAR(4) NOT NULL,
STREET CHAR(10) NOT NULL,
CITY CHAR(10) NOT NULL,
PROVINCE CHAR(2) NOT NULL,
POSTAL_CODE CHAR(6) NOT NULL,
TYPE_OF_BUSINESS CHAR(2),
PRIMARY KEY (OWNER_NO),
CHECK (PROVINCE IN ('AL','BC','MA','NB','NF','NT','NS','NU',
'ON','PE','QB','SA','YU')),
CHECK (('A'<=SUBSTR(POSTAL_CODE,1,1) AND SUBSTR(POSTAL_CODE,1,1)<='Z')
AND ('0'<=SUBSTR(POSTAL_CODE,2,1) AND SUBSTR(POSTAL_CODE,2,1)<='9') AND
('A'<=SUBSTR(POSTAL_CODE,3,1) AND SUBSTR(POSTAL_CODE,3,1)<='Z') AND
('0'<=SUBSTR(POSTAL_CODE,4,1) AND SUBSTR(POSTAL_CODE,4,1)<='9') AND
('A'<=SUBSTR(POSTAL_CODE,5,1) AND SUBSTR(POSTAL_CODE,5,1)<='Z') AND
('0'<=SUBSTR(POSTAL_CODE,6,1) AND SUBSTR(POSTAL_CODE,6,1)<='9')),
CHECK(TYPE_OF_BUSINESS IS NULL OR (FIRST_NAME IS NULL AND
MIDDLE_NAME IS NULL))
)
CREATE TABLE RENTER (
RENTER_NO CHAR(4) NOT NULL,
NAME CHAR(20) NOT NULL,
FIRST_NAME CHAR(10),
MIDDLE_NAME CHAR(10),
STREET_NO CHAR(4) NOT NULL,
STREET CHAR(10) NOT NULL,
CITY CHAR(10) NOT NULL,
PROVINCE CHAR(2) NOT NULL,
POSTAL_CODE CHAR(6) NOT NULL,
TYPE_OF_BUSINESS CHAR(2),
PRIMARY KEY (RENTER_NO),
CHECK (PROVINCE IN ('AL','BC','MA','NB','NF','NT','NS','NU','ON',
'PE','QB','SA','YU')),
CHECK (('A'<=SUBSTR(POSTAL_CODE,1,1) AND SUBSTR(POSTAL_CODE,1,1)<='Z')
AND ('0'<=SUBSTR(POSTAL_CODE,2,1) AND SUBSTR(POSTAL_CODE,2,1)<='9') AND
('A'<=SUBSTR(POSTAL_CODE,3,1) AND SUBSTR(POSTAL_CODE,3,1)<='Z') AND
('0'<=SUBSTR(POSTAL_CODE,4,1) AND SUBSTR(POSTAL_CODE,4,1)<='9') AND
('A'<=SUBSTR(POSTAL_CODE,5,1) AND SUBSTR(POSTAL_CODE,5,1)<='Z') AND
('0'<=SUBSTR(POSTAL_CODE,6,1) AND SUBSTR(POSTAL_CODE,6,1)<='9')),
CHECK(TYPE_OF_BUSINESS IS NULL OR (FIRST_NAME IS NULL AND MIDDLE_NAME
IS NULL))
)
CREATE TABLE PROPERTY (
PROPERTY_NO CHAR(4) NOT NULL,
STREET_NO CHAR(4) NOT NULL,
STREET CHAR(10) NOT NULL,
CITY CHAR(10) NOT NULL,
PROVINCE CHAR(2) NOT NULL,
POSTAL_CODE CHAR(6) NOT NULL,
OVERSEEN_BY CHAR(4) NOT NULL,
OWNED_BY CHAR(4) NOT NULL,
TYPE CHAR(2) NOT NULL,
PRIMARY KEY (PROPERTY_NO),
FOREIGN KEY (OVERSEEN_BY) REFERENCES STAFF,
FOREIGN KEY (OWNED_BY) REFERENCES OWNER,
CHECK (PROVINCE IN ('AL','BC','MA','NB','NF','NT','NS','NU','ON',
'PE','QB','SA','YU')),
CHECK (('A'<=SUBSTR(POSTAL_CODE,1,1) AND SUBSTR(POSTAL_CODE,1,1)<='Z')
AND ('0'<=SUBSTR(POSTAL_CODE,2,1) AND SUBSTR(POSTAL_CODE,2,1)<='9')
AND ('A'<=SUBSTR(POSTAL_CODE,3,1) AND SUBSTR(POSTAL_CODE,3,1)<='Z')
AND ('0'<=SUBSTR(POSTAL_CODE,4,1) AND SUBSTR(POSTAL_CODE,4,1)<='9')
AND ('A'<=SUBSTR(POSTAL_CODE,5,1) AND SUBSTR(POSTAL_CODE,5,1)<='Z')
AND ('0'<=SUBSTR(POSTAL_CODE,6,1) AND SUBSTR(POSTAL_CODE,6,1)<='9'))
)
CREATE TABLE RENTAL_AGREEMENT (
PROPERTY_NO CHAR(4) NOT NULL,
RENTAL_NO CHAR(4) NOT NULL,
SIGNING_DATE DATE NOT NULL,
STARTING_DATE DATE NOT NULL,
ENDING_DATE DATE NOT NULL,
RENTER_NO CHAR(4) NOT NULL,
PRIMARY KEY (PROPERTY_NO,RENTAL_NO),
FOREIGN KEY (PROPERTY_NO) REFERENCES PROPERTY,
FOREIGN KEY (RENTER_NO) REFERENCES RENTER, CHECK
(SIGNING_DATE <= STARTING_DATE),
CHECK (STARTING_DATE <= ENDING_DATE)
)
CREATE TABLE RENTER_EMAIL (
EMAIL_ADDR CHAR(20) NOT NULL,
RENTER_NO CHAR(4) NOT NULL, PRIMARY KEY
(EMAIL_ADDR,RENTER_NO), FOREIGN KEY
(RENTER_NO) REFERENCES RENTER
)
CREATE TABLE STAFF_EMAIL (
EMAIL_ADDR CHAR(20) NOT NULL,
STAFF_NO CHAR(4) NOT NULL, PRIMARY KEY
(EMAIL_ADDR,STAFF_NO), FOREIGN KEY
(STAFF_NO) REFERENCES STAFF
)
CREATE TABLE OWNER_EMAIL (
EMAIL_ADDR CHAR(20) NOT NULL,
OWNER_NO CHAR(4) NOT NULL, PRIMARY KEY
(EMAIL_ADDR,OWNER_NO), FOREIGN KEY
(OWNER_NO) REFERENCES OWNER
)
CREATE TABLE BRANCH_EMAIL (
EMAIL_ADDR CHAR(20) NOT NULL,
BRANCH_NO CHAR(4) NOT NULL,
PRIMARY KEY (EMAIL_ADDR,BRANCH_NO), FOREIGN
KEY (BRANCH_NO) REFERENCES BRANCH
)
CREATE TABLE RENTER_PHONE (
AREA_CODE CHAR(3) NOT NULL,
PHONE_NO CHAR(7) NOT NULL,
EXTENSION VARCHAR(5),
RENTER_NO CHAR(4) NOT NULL,
PRIMARY KEY (AREA_CODE,PHONE_NO,RENTER_NO),
FOREIGN KEY (RENTER_NO) REFERENCES RENTER,
CHECK(('0'<=SUBSTR(AREA_CODE,1,1) AND SUBSTR(AREA_CODE,1,1)<='9')
AND ('0'<=SUBSTR(AREA_CODE,2,1) AND SUBSTR(AREA_CODE,2,1)<='9') AND
('0'<=SUBSTR(AREA_CODE,3,1) AND SUBSTR(AREA_CODE,3,1)<='9')),
CHECK(('0'<=SUBSTR(PHONE_NO,1,1) AND SUBSTR(PHONE_NO,1,1)<='9') AND
('0'<=SUBSTR(PHONE_NO,2,1) AND SUBSTR(PHONE_NO,2,1)<='9') AND
('0'<=SUBSTR(PHONE_NO,3,1) AND SUBSTR(PHONE_NO,3,1)<='9') AND
('0'<=SUBSTR(PHONE_NO,4,1) AND SUBSTR(PHONE_NO,4,1)<='9') AND
('0'<=SUBSTR(PHONE_NO,5,1) AND SUBSTR(PHONE_NO,5,1)<='9') AND
('0'<=SUBSTR(PHONE_NO,6,1) AND SUBSTR(PHONE_NO,6,1)<='9') AND
('0'<=SUBSTR(PHONE_NO,7,1) AND SUBSTR(PHONE_NO,7,1)<='9'))
)
CREATE TABLE STAFF_PHONE (
AREA_CODE CHAR(3) NOT NULL,
PHONE_NO CHAR(7) NOT NULL,
EXTENSION VARCHAR(5),
STAFF_NO CHAR(4) NOT NULL,
PRIMARY KEY (AREA_CODE,PHONE_NO,STAFF_NO),
FOREIGN KEY (STAFF_NO) REFERENCES STAFF,
CHECK(('0'<=SUBSTR(AREA_CODE,1,1) AND SUBSTR(AREA_CODE,1,1)<='9')
AND ('0'<=SUBSTR(AREA_CODE,2,1) AND SUBSTR(AREA_CODE,2,1)<='9') AND
('0'<=SUBSTR(AREA_CODE,3,1) AND SUBSTR(AREA_CODE,3,1)<='9')),
CHECK(('0'<=SUBSTR(PHONE_NO,1,1) AND SUBSTR(PHONE_NO,1,1)<='9') AND
('0'<=SUBSTR(PHONE_NO,2,1) AND SUBSTR(PHONE_NO,2,1)<='9') AND
('0'<=SUBSTR(PHONE_NO,3,1) AND SUBSTR(PHONE_NO,3,1)<='9') AND
('0'<=SUBSTR(PHONE_NO,4,1) AND SUBSTR(PHONE_NO,4,1)<='9') AND
('0'<=SUBSTR(PHONE_NO,5,1) AND SUBSTR(PHONE_NO,5,1)<='9') AND
('0'<=SUBSTR(PHONE_NO,6,1) AND SUBSTR(PHONE_NO,6,1)<='9') AND
('0'<=SUBSTR(PHONE_NO,7,1) AND SUBSTR(PHONE_NO,7,1)<='9'))
)
CREATE TABLE OWNER_PHONE (
AREA_CODE CHAR(3) NOT NULL,
PHONE_NO CHAR(7) NOT NULL,
EXTENSION VARCHAR(5),
OWNER_NO CHAR(4) NOT NULL,
PRIMARY KEY (AREA_CODE,PHONE_NO,OWNER_NO),
FOREIGN KEY (OWNER_NO) REFERENCES OWNER,
CHECK(('0'<=SUBSTR(AREA_CODE,1,1) AND SUBSTR(AREA_CODE,1,1)<='9')
AND ('0'<=SUBSTR(AREA_CODE,2,1) AND SUBSTR(AREA_CODE,2,1)<='9') AND
('0'<=SUBSTR(AREA_CODE,3,1) AND SUBSTR(AREA_CODE,3,1)<='9')),
CHECK(('0'<=SUBSTR(PHONE_NO,1,1) AND SUBSTR(PHONE_NO,1,1)<='9') AND
('0'<=SUBSTR(PHONE_NO,2,1) AND SUBSTR(PHONE_NO,2,1)<='9')
AND ('0'<=SUBSTR(PHONE_NO,3,1) AND SUBSTR(PHONE_NO,3,1)<='9')
AND ('0'<=SUBSTR(PHONE_NO,4,1) AND SUBSTR(PHONE_NO,4,1)<='9')
AND ('0'<=SUBSTR(PHONE_NO,5,1) AND SUBSTR(PHONE_NO,5,1)<='9')
AND ('0'<=SUBSTR(PHONE_NO,6,1) AND SUBSTR(PHONE_NO,6,1)<='9')
AND ('0'<=SUBSTR(PHONE_NO,7,1) AND SUBSTR(PHONE_NO,7,1)<='9'))
)
CREATE TABLE BRANCH_PHONE (
AREA_CODE CHAR(3) NOT NULL,
PHONE_NO CHAR(7) NOT NULL,
EXTENSION VARCHAR(5),
BRANCH_NO CHAR(4) NOT NULL,
PRIMARY KEY (AREA_CODE,PHONE_NO,BRANCH_NO),
FOREIGN KEY (BRANCH_NO) REFERENCES BRANCH,
CHECK(('0'<=SUBSTR(AREA_CODE,1,1) AND SUBSTR(AREA_CODE,1,1)<='9')
AND ('0'<=SUBSTR(AREA_CODE,2,1) AND SUBSTR(AREA_CODE,2,1)<='9') AND
('0'<=SUBSTR(AREA_CODE,3,1) AND SUBSTR(AREA_CODE,3,1)<='9')),
CHECK(('0'<=SUBSTR(PHONE_NO,1,1) AND SUBSTR(PHONE_NO,1,1)<='9') AND
('0'<=SUBSTR(PHONE_NO,2,1) AND SUBSTR(PHONE_NO,2,1)<='9') AND
('0'<=SUBSTR(PHONE_NO,3,1) AND SUBSTR(PHONE_NO,3,1)<='9') AND
('0'<=SUBSTR(PHONE_NO,4,1) AND SUBSTR(PHONE_NO,4,1)<='9') AND
('0'<=SUBSTR(PHONE_NO,5,1) AND SUBSTR(PHONE_NO,5,1)<='9') AND
('0'<=SUBSTR(PHONE_NO,6,1) AND SUBSTR(PHONE_NO,6,1)<='9') AND
('0'<=SUBSTR(PHONE_NO,7,1) AND SUBSTR(PHONE_NO,7,1)<='9'))
)
CREATE TABLE VIEWING (
PROPERTY_NO CHAR(4) NOT NULL,
RENTER_NO CHAR(4) NOT NULL,
VIEWING_DATE DATE NOT NULL,
PRIMARY KEY (PROPERTY_NO,VIEWING_DATE,RENTER_NO),
FOREIGN KEY (PROPERTY_NO) REFERENCES PROPERTY,
FOREIGN KEY (RENTER_NO) REFERENCES RENTER
)
CREATE TABLE NEWSPAPER (
PAPER_NAME CHAR(20) NOT NULL,
PRIMARY KEY (PAPER_NAME)
)
CREATE TABLE ADVERTISEMENT (
PAPER_NAME CHAR(20) NOT NULL,
AD_NO CHAR(4) NOT NULL,
AD_DATE DATE NOT NULL,
PROPERTY_NO CHAR(4) NOT NULL,
PRIMARY KEY (PAPER_NAME,AD_NO),
FOREIGN KEY (PAPER_NAME) REFERENCES NEWSPAPER,
FOREIGN KEY (PROPERTY_NO) REFERENCES PROPERTY
)
ALTER TABLE BRANCH
ADD CONSTRAINT MANAGER_CNST FOREIGN KEY (MANAGER) REFERENCES
STAFF(STAFF_NO)
Sample Queries
Query 1: Give the staff number of each of the staff members whose salary is greater
than 5000. Please, sort them by the staff number.
SELECT STAFF_NO FROM STAFF
WHERE SALARY > 5000
ORDER BY STAFF_NO
Query 2: Give the renter number of each of the renters who has a viewing record.
Please avoid duplications.
SELECT DISTINCT RENTER_NO FROM VIEWING
Query 3: Give the dates of all the advertisements posted in THE GLOBE AND MAIL in
2005. Please, avoid duplications.
SELECT DISTINCT AD_DATE FROM ADVERTISEMENT
WHERE PAPER_NAME = 'THE GLOBE AND MAIL' AND AD_DATE>='2005-01-01'
AND AD_DATE<='2005-12-31'
ORDER BY AD_DATE
Query 4: Give the email addresses and the renter number for all the private renters.
Please, sort them by the renter number.
SELECT EMAIL_ADDR, RENTER.RENTER_NO
FROM RENTER_EMAIL, RENTER
WHERE RENTER_EMAIL.RENTER_NO = RENTER.RENTER_NO
AND TYPE_OF_BUSINESS IS NULL
ORDER BY RENTER.RENTER_NO
Query 5: Find the properties that are already advertised but not yet rented. Please, avoid
duplications.
SELECT DISTINCT PROPERTY_NO FROM ADVERTISEMENT
WHERE PROPERTY_NO NOT IN (SELECT DISTINCT PROPERTY_NO
FROM RENTAL_AGREEMENT)
Query 6: Give the names and the branch numbers of all the staff members working in the
branch which is located in Hamilton. The names should be listed in an
alphabetic order (by last, then by first, then by middle names).
SELECT FIRST_NAME,MIDDLE_NAME,LAST_NAME,BRANCH_NO
FROM STAFF,BRANCH
WHERE STAFF.ALLOCATED_TO=BRANCH.BRANCH_NO
AND BRANCH.CITY='HAMILTON'
ORDER BY LAST_NAME,FIRST_NAME,MIDDLE_NAME
Query 7: Give the staff numbers and the names of all the workers who live on the same
street, city, and province as their manager. The names should be listed in an
alphabetic order (by last, then by first, then by middle names).
Query 8: Find the branch number and the average salary of the branch that has the highest
average salary. Please, call the branch number as branch_no and the
average salary as avg_salary.
Our users are identified by name (at most 20 characters), email (at most 20
characters), and a unique user id (8 characters long). They can be either guest users or
subscribed users (subscribers for short). The subscribers have passwords (at most 8
characters) and we keep the date of the subscription. They need the password to access
our website to file bug reports or upload software projects or update patches. A user can
download any project, the number of downloads per user per project is recorded. The
subscribers can file bug reports for any project. Every bug identified has an id (a positive
integer) and a description (text of at most 256 characters). The bug id’s must be unique
for all bugs concerning the same project. The date of filing of a bug report is recorded.
Each bug report deals with a single project and can report a single bug. Each bug report is
made by a single subscriber.
Logical Model
Table Schema:
CREATE TABLE USER (
USER_ID CHAR(8) NOT NULL,
NAME CHAR(20) NOT NULL,
EMAIL CHAR(20),
NOF_DOWNLOADS INTEGER NOT NULL,
PRIMARY KEY (USER_ID)
)
CREATE TABLE GUEST (
USER_ID CHAR(8) NOT NULL,
PRIMARY KEY (USER_ID),
FOREIGN KEY (USER_ID) REFERENCES USER
)
CREATE TABLE SUBSCRIBER (
USER_ID CHAR(8) NOT NULL,
SUBSCRDATE DATE NOT NULL,
PASSWORD CHAR(8) NOT NULL,
PRIMARY KEY (USER_ID),
FOREIGN KEY (USER_ID) REFERENCES USER
)
CREATE TABLE NONDEVELOPER (
USER_ID CHAR(8) NOT NULL,
PRIMARY KEY (USER_ID),
FOREIGN KEY (USER_ID) REFERENCES SUBSCRIBER
)
CREATE TABLE DEVELOPER (
USER_ID CHAR(8) NOT NULL,
PRIMARY KEY (USER_ID),
FOREIGN KEY (USER_ID) REFERENCES SUBSCRIBER
)
CREATE TABLE PROJECT (
PROJECT_ID CHAR(8) NOT NULL,
STATUS CHAR(1) NOT NULL,
DESCRIPTION CHAR(254),
OWNED_BY CHAR(8) NOT NULL,
PRIMARY KEY (PROJECT_ID),
FOREIGN KEY (OWNED_BY) REFERENCES DEVELOPER
)
CREATE TABLE DEPENDS (
PROJECT_ID CHAR(8) NOT NULL,
DEPENDS_ON CHAR(8) NOT NULL, PRIMARY KEY
(PROJECT_ID,DEPENDS_ON), FOREIGN KEY
(PROJECT_ID) REFERENCES PROJECT, FOREIGN KEY
(DEPENDS_ON) REFERENCES PROJECT
)
CREATE TABLE CATEGORY (
PROJECT_ID CHAR(8) NOT NULL,
CAT CHAR(1) NOT NULL,
PRIMARY KEY (PROJECT_ID,CAT),
FOREIGN KEY (PROJECT_ID) REFERENCES PROJECT
)
Query 2: Give project id of all projects that have more than two update patches.
SELECT PROJECT_ID
FROM (SELECT PROJECT.PROJECT_ID,C
FROM PROJECT, (SELECT PROJECT_ID,COUNT(*) AS C FROM
PATCH GROUP BY PROJECT_ID) AS T
WHERE PROJECT.PROJECT_ID=T.PROJECT_ID)
WHERE C > 2
Query 3: For each project, give the number of all update patches and the number of all
downloads.
SELECT T.PROJECT_ID,PATCH_COUNT,DOWNLOAD_COUNT
FROM (SELECT PROJECT_ID,COUNT(*) AS PATCH_COUNT
FROM PATCH GROUP BY PROJECT_ID) AS T,
(SELECT PROJECT_ID,COUNT(*) AS DOWNLOAD_COUNT
FROM DOWNLOAD GROUP BY PROJECT_ID) AS S
WHERE T.PROJECT_ID=S.PROJECT_ID
Query 4: Give the project id of the projects with the most downloads.
SELECT PROJECT_ID
FROM (SELECT PROJECT_ID,COUNT(*) AS
DOWNLOAD_COUNT FROM DOWNLOAD GROUP BY
PROJECT_ID), (SELECT MAX(DC) AS MAXDC
FROM (SELECT COUNT(*) AS DC FROM
DOWNLOAD GROUP BY PROJECT_ID))
WHERE DOWNLOAD_COUNT=MAXDC
Query 5: Give the project id of the projects with the most update patches.
SELECT PROJECT_ID
FROM (SELECT PROJECT_ID,COUNT(*) AS PATCH_COUNT
FROM PATCH GROUP BY PROJECT_ID),
(SELECT MAX(PC) AS MAXPC
FROM (SELECT COUNT(*) AS PC
FROM PATCH GROUP BY PROJECT_ID))
WHERE PATCH_COUNT=MAXPC
Query 6: For each project, give project id of all projects that the project depends on.
SELECT *
FROM DEPENDS
Query 7: Give project id of all projects that do not depend on any other project.
Query 8: Give the project id of the projects that depend on the most other projects.
SELECT T.PROJECT_ID
FROM (SELECT PROJECT_ID,COUNT(*) AS
DEPEND_COUNT FROM DEPENDS GROUP BY
PROJECT_ID) AS T, (SELECT MAX(DC) AS MAXDC
FROM (SELECT COUNT(*) AS DC
FROM DEPENDS GROUP BY PROJECT_ID))
WHERE T.DEPEND_COUNT = MAXDC
Query 9: Give description, bug id, and project id of all bug reports for all projects
that have most bug reports.
SELECT BUG_ID,BUG.PROJECT_ID,DESCRIPTION
FROM BUG, (SELECT T.PROJECT_ID,T.BC
FROM (SELECT PROJECT_ID,COUNT(*) AS BC
FROM BUG GROUP BY PROJECT_ID) AS T,
(SELECT MAX(BC1) AS MAXBC
FROM (SELECT COUNT(*) AS BC1
FROM BUG GROUP BY PROJECT_ID))
WHERE T.BC=MAXBC) AS S
WHERE BUG.PROJECT_ID=S.PROJECT_ID
Query 10: Give user id of a developer with the least amount of bug reports.
SELECT USER_ID
FROM (SELECT USER_ID,COUNT(*) AS BPD
FROM (SELECT BUG_ID,BUG.PROJECT_ID,USER_ID
FROM BUG,PROJECT,DEVELOPER
WHERE BUG.PROJECT_ID=PROJECT.PROJECT_ID
AND OWNED_BY=USER_ID)
GROUP BY USER_ID)
WHERE BPD IN (SELECT MIN(BPD) AS MINBPD
FROM (SELECT USER_ID,COUNT(*) AS BPD
FROM (SELECT BUG_ID,BUG.PROJECT_ID,USER_ID
FROM BUG,PROJECT,DEVELOPER
WHERE BUG.PROJECT_ID=PROJECT.PROJECT_ID
DBMS Case Study
Topic:-Tour Operator System
Case Description:-The system need to keep track of people. For each person, it records
all his/her address, of which exactly one is designated as the mailing address (so each
person has at least one address). Each address consists of country, province/state, city,
street, street number, P.O. Box number, and a list (possible empty) of phone numbers to
the location of the address and a list (possible empty) of fax numbers to the location of
the address. In addition to the list of addresses for each person it records a list (possible
empty) of cell phone numbers and a list (possible empty) of email address. Each person
in the database can be an old customer (have taken a tour of the company), a current
customer (is booked to take a tour or is on a tour right now), a tour guide, an employee
(works for the tour company), or any mixture of these (for instance an employee can take
a tour and so can be a customer as well, or an employee can work as a tour guide for a
particular tour and hence be an employee and a guide at the same time etc.). The sex and
age of each person must also be recorded, a date-of-birth is optional for an external
worker, a contract reference for each of the tours the guide is doing must be included. A
guide contract references the tour (see below) and the total amount the tour guide will be
paid for the tour. The guides do not pay for the accommodation and the meals.
The system also keeps track of all tours, past and future. Each tour has a unique
designation, itinerary, guide (at least one, but may be more than one), its status
(completed, in-progress, in-the-future), and the list of participants (not including the
guides). The itinerary consists of list of the dates the tour covers and for each date it
includes the place of breakfast, the place of lunch, the place of diner, and the place of
accommodation. For each of the places there is a contract reference. Each day in the
itinerary also includes and a simple English description of the activities during that day.
uses the accommodation. All prices are assumed to be in Canadian dollars, not
conversion is involved, regardless where the place is. Each place is identified by a single
address. Each provider of accommodation or meal has a unique designation.
Logical Model
Figure: The Tour Operator System Logical Model
Table schema
CREATE TABLE PERSONS(
PID SMALLINT NOT NULL,
NAME VARCHAR(20) NOT NULL,
SEX CHAR(1) NOT NULL CHECK (SEX IN ('M','F')),
AGE SMALLINT NOT NULL CHECK (AGE BETWEEN 0 AND 150),
BIRTHDATE DATE NOT NULL,
PRIMARY KEY(PID),
CONSTRAINT AGECHECK CHECK (2003-YEAR(BIRTHDATE)=AGE)
)
CREATE TABLE HASE(
PID SMALLINT NOT NULL,
EADDR VARCHAR(30) NOT NULL,
PRIMARY KEY(PID,EADDR),
FOREIGN KEY (PID) REFERENCES PERSONS (PID)
)
CREATE TABLE HASCE(
PID SMALLINT NOT NULL,
PHONENO VARCHAR(20) NOT NULL,
PRIMARY KEY(PID,PHONENO),
FOREIGN KEY (PID) REFERENCES PERSONS (PID)
)
CREATE TABLE ADDRESSES(
adID SMALLINT NOT NULL,
COUNTRY CHAR(3) NOT NULL,
CITY VARCHAR(10) NOT NULL,
STREET VARCHAR(10),
STRNO VARCHAR(10),
POBox VARCHAR(10),
PRIMARY KEY(adID),
CONSTRAINT ADDRCHECK1
CHECK (NOT ((STREET IS NOT NULL) AND (POBox IS NOT NULL))),
CONSTRAINT ADDRCHECK2
CHECK (NOT ((STRNO IS NOT NULL) AND (POBox IS NOT NULL))),
CONSTRAINT ADDRCHECK3
CHECK (NOT ((STREET IS NOT NULL) AND (STRNO IS NULL))),
CONSTRAINT ADDRCHECK4
CHECK (NOT ((STRNO IS NOT NULL) AND (STREET IS NULL)))
)
CREATE TABLE HASA(
PID SMALLINT NOT NULL,
adID SMALLINT NOT NULL,
PRIMARY KEY(PID,adID),
FOREIGN KEY (PID) REFERENCES PERSONS (PID),
FOREIGN KEY (adID) REFERENCES ADDRESSES (adID)
)
CREATE TABLE PHONES(
PHONENO VARCHAR(20) NOT NULL,
PRIMARY KEY(PHONENO)
)
CREATE TABLE FAXES(
PHONENO VARCHAR(20) NOT NULL,
PRIMARY KEY(PHONENO)
)
CREATE TABLE HASP(
adID SMALLINT NOT NULL,
PHONENO VARCHAR(20) NOT NULL,
PRIMARY KEY(PHONENO),
FOREIGN KEY (adID) REFERENCES ADDRESSES (adID),
FOREIGN KEY (PHONENO) REFERENCES PHONES (PHONENO)
)
CREATE TABLE HASF(
adID SMALLINT NOT NULL,
PHONENO VARCHAR(20) NOT NULL,
PRIMARY KEY(PHONENO),
FOREIGN KEY (adID) REFERENCES ADDRESSES (adID),
FOREIGN KEY (PHONENO) REFERENCES FAXES (PHONENO)
)
CREATE TABLE EMPLOYEES(
PID SMALLINT NOT NULL,
PRIMARY KEY(PID),
FOREIGN KEY (PID) REFERENCES PERSONS (PID)
)
CREATE TABLE CUSTOMERS(
PID SMALLINT NOT NULL,
PRIMARY KEY(PID),
FOREIGN KEY (PID) REFERENCES PERSONS (PID)
)
CREATE TABLE GUIDES(
PID SMALLINT NOT NULL,
PRIMARY KEY(PID),
FOREIGN KEY (PID) REFERENCES PERSONS (PID)
)
CREATE TABLE TOURS(
DESIG VARCHAR(5) NOT NULL,
STATUS CHAR(3) NOT NULL CHECK (STATUS IN ('P','I','F')),
PRIMARY KEY(DESIG)
)
CREATE TABLE PARTICIP(
PID SMALLINT NOT NULL,
DESIG VARCHAR(5) NOT NULL,
PRIMARY KEY (PID,DESIG),
FOREIGN KEY (PID) REFERENCES CUSTOMERS (PID),
FOREIGN KEY (DESIG) REFERENCES TOURS (DESIG)
)
CREATE TABLE HASCO(
PID SMALLINT NOT NULL,
DESIG VARCHAR(5) NOT NULL,
AMOUNT DECIMAL(9,2) NOT NULL,
PRIMARY KEY (PID,DESIG),
FOREIGN KEY (PID) REFERENCES GUIDES (PID),
FOREIGN KEY (DESIG) REFERENCES TOURS (DESIG)
)
CREATE TABLE ITINERARIES(
DESIG VARCHAR(5) NOT NULL,
DATE DATE NOT NULL,
DESCR VARCHAR(256),
PRIMARY KEY (DESIG,DATE),
FOREIGN KEY (DESIG) REFERENCES TOURS (DESIG)
)
CREATE TABLE PROVIDERS(
DESIGN VARCHAR(10) NOT NULL,
PRIMARY KEY (DESIGN)
)
CREATE TABLE PLACES(
adID SMALLINT NOT NULL,
DESIGN VARCHAR(10) NOT NULL,
PRIMARY KEY (adID),
FOREIGN KEY (adID) REFERENCES ADDRESSES (adID),
FOREIGN KEY (DESIGN) REFERENCES PROVIDERS (DESIGN)
)
CREATE TABLE ISBP(
AMOUNT DECIMAL(9,2) NOT NULL,
VALID_DATE DATE NOT NULL,
PRICING CHAR(1) NOT NULL CHECK (PRICING IN ('G','P')),
FROMD DATE NOT NULL,
TOD DATE NOT NULL,
MINP SMALLINT NOT NULL,
MAXP SMALLINT NOT NULL,
PENALTY DECIMAL(9,2) NOT NULL,
DESIG VARCHAR(5) NOT NULL,
DATE DATE NOT NULL,
adID SMALLINT NOT NULL,
PRIMARY KEY (DESIG,DATE),
FOREIGN KEY (DESIG,DATE) REFERENCES ITINERARIES (DESIG,DATE),
FOREIGN KEY (adID) REFERENCES PLACES (adID),
CONSTRAINT ISBP_DATE1 CHECK (VALID_DATE < FROMD),
CONSTRAINT ISBP_DATE2 CHECK (FROMD <= TOD),
CONSTRAINT ISBP_DATE3 CHECK (FROMD <= DATE),
CONSTRAINT ISBP_DATE4 CHECK (DATE <= TOD),
CONSTRAINT ISBP_PER1 CHECK (MINP <= MAXP)
)
CREATE TABLE ISLP(
AMOUNT DECIMAL(9,2) NOT NULL,
VALID_DATE DATE NOT NULL,
PRICING CHAR(1) NOT NULL CHECK (PRICING IN ('G','P')),
FROMD DATE NOT NULL,
TOD DATE NOT NULL,
MINP SMALLINT NOT NULL,
MAXP SMALLINT NOT NULL,
PENALTY DECIMAL(9,2) NOT NULL,
DESIG VARCHAR(5) NOT NULL,
DATE DATE NOT NULL,
adID SMALLINT NOT NULL,
PRIMARY KEY (DESIG,DATE),
FOREIGN KEY (DESIG,DATE) REFERENCES ITINERARIES (DESIG,DATE),
FOREIGN KEY (adID) REFERENCES PLACES (adID),
CONSTRAINT ISLP_DATE1 CHECK (VALID_DATE < FROMD),
CONSTRAINT ISLP_DATE2 CHECK (FROMD <= TOD),
CONSTRAINT ISLP_DATE3 CHECK (FROMD <= DATE),
CONSTRAINT ISLP_DATE4 CHECK (DATE <= TOD),
CONSTRAINT ISLP_PER1 CHECK (MINP <= MAXP)
)
CREATE TABLE ISDP(
AMOUNT DECIMAL(9,2) NOT NULL,
VALID_DATE DATE NOT NULL,
PRICING CHAR(1) NOT NULL CHECK (PRICING IN ('G','P')),
FROMD DATE NOT NULL,
TOD DATE NOT NULL,
MINP SMALLINT NOT NULL,
MAXP SMALLINT NOT NULL,
PENALTY DECIMAL(9,2) NOT NULL,
DESIG VARCHAR(5) NOT NULL,
DATE DATE NOT NULL,
adID SMALLINT NOT NULL,
PRIMARY KEY (DESIG,DATE),
FOREIGN KEY (DESIG,DATE) REFERENCES ITINERARIES (DESIG,DATE),
FOREIGN KEY (adID) REFERENCES PLACES (adID),
CONSTRAINT ISDP_DATE1 CHECK (VALID_DATE < FROMD),
CONSTRAINT ISDP_DATE2 CHECK (FROMD <= TOD),
CONSTRAINT ISDP_DATE3 CHECK (FROMD <= DATE),
CONSTRAINT ISDP_DATE4 CHECK (DATE <= TOD),
CONSTRAINT ISDP_PER1 CHECK (MINP <= MAXP)
)
CREATE TABLE ISSP(
AMOUNT DECIMAL(9,2) NOT NULL,
VALID_DATE DATE NOT NULL,
PRICING CHAR(1) NOT NULL CHECK (PRICING IN ('G','P')),
FROMD DATE NOT NULL,
TOD DATE NOT NULL,
MINP SMALLINT NOT NULL,
MAXP SMALLINT NOT NULL,
PENALTY DECIMAL(9,2) NOT NULL,
DESIG VARCHAR(5) NOT NULL,
DATE DATE NOT NULL,
adID SMALLINT NOT NULL,
PRIMARY KEY (DESIG,DATE),
FOREIGN KEY (DESIG,DATE) REFERENCES ITINERARIES
(DESIG,DATE),
FOREIGN KEY (adID) REFERENCES PLACES (adID),
CONSTRAINT ISSP_DATE1 CHECK (VALID_DATE < FROMD),
CONSTRAINT ISSP_DATE2 CHECK (FROMD <= TOD),
CONSTRAINT ISSP_DATE3 CHECK (FROMD <= DATE),
CONSTRAINT ISSP_DATE4 CHECK (DATE <= TOD),
CONSTRAINT ISSP_PER1 CHECK (MINP <= MAXP)
)
Sample Queries
Query 1: list all customers, old and current.
SELECT CUSTOMERS.PID,NAME FROM CUSTOMERS,PERSONS
WHERE CUSTOMERS.PID=PERSONS.PID
Query 3: For a given guide, find all the tours he/she guided or will guide and the
amount he/she got/will get for the guiding the tour
SELECT HASCO.PID,NAME,DESIG,AMOUNT FROM HASCO,PERSONS
WHERE HASCO.PID=0 AND PERSONS.PID=0
Query 5: List all guides that guided a tour that had a lunch in a given place.
SELECT DISTINCT HASCO.PID,NAME FROM HASCO,ISLP,PERSONS
WHERE HASCO.DESIG=ISLP.DESIG AND ISLP.adID=100 AND HASCO.PID=PERSONS.PID
Query 8: List the tours that will have breakfast at a given place on a given date .
SELECT TOURS.DESIG FROM TOURS,ISBP
WHERE TOURS.DESIG=ISBP.DESIG AND ISBP.DATE='12/18/2002' AND adID=100
Query 9: List all employees that have guided or will guide a tour or who have taken or
will taken a tour.
SELECT DISTINCT EMPLOYEES.PID,NAME FROM
EMPLOYEES,GUIDES,CUSTOMERS,PERSONS
WHERE (EMPLOYEES.PID=GUIDES.PID OR EMPLOYEES.PID=CUSTOMERS.PID)
AND EMPLOYEES.PID=PERSONS.PID
Query 10: List all customers booked for a tour starting later or on a given date.
SELECT DISTINCT PARTICIP.PID,NAME FROM PARTICIP,ITINERARIES,PERSONS
WHERE PARTICIP.DESIG=ITINERARIES.DESIG
AND ITINERARIES.DATE >= '12/18/2003' AND PARTICIP.PID=PERSONS.PID
AND NOT EXISTS (SELECT ITINERARIES.DATE FROM ITINERARIES
WHERE ITINERARIES.DATE < '12/18/2003'
AND ITINERARIES.DESIG=PARTICIP.DESIG)
Logical Model
Table Schema:
CREATE TABLE EMPLOYEE (
EMPLOYEENO CHAR(6) NOT NULL,
PRIMARY KEY (EMPLOYEENO),
CHECK (('0' <= SUBSTR(EMPLOYEENO,1,1) AND SUBSTR(EMPLOYEENO,1,1) <= '9')
AND ('0' <= SUBSTR(EMPLOYEENO,2,1) AND SUBSTR(EMPLOYEENO,2,1) <= '9')
AND ('0' <= SUBSTR(EMPLOYEENO,3,1) AND SUBSTR(EMPLOYEENO,3,1) <= '9')
AND ('0' <= SUBSTR(EMPLOYEENO,4,1) AND SUBSTR(EMPLOYEENO,4,1) <= '9')
AND ('0' <= SUBSTR(EMPLOYEENO,5,1) AND SUBSTR(EMPLOYEENO,5,1) <= '9')
AND ('0' <= SUBSTR(EMPLOYEENO,6,1) AND SUBSTR(EMPLOYEENO,6,1) <= '9'))
)
CREATE TABLE MANAGER (
EMPLOYEENO CHAR(6) NOT NULL,
PRIMARY KEY (EMPLOYEENO),
FOREIGN KEY (EMPLOYEENO) REFERENCES EMPLOYEE
)
CREATE TABLE WORKER (
EMPLOYEENO CHAR(6) NOT NULL,
MANAGERNO CHAR(6) NOT NULL,
PRIMARY KEY (EMPLOYEENO),
FOREIGN KEY (EMPLOYEENO) REFERENCES EMPLOYEE,
FOREIGN KEY (MANAGERNO) REFERENCES MANAGER(EMPLOYEENO)
)
CREATE TABLE HASPHONE (
EMPLOYEENO CHAR(6) NOT NULL,
AREA_CODE CHAR(3) NOT NULL,
NUMBER CHAR(6) NOT NULL,
PRIMARY KEY (EMPLOYEENO,AREA_CODE,NUMBER),
FOREIGN KEY (EMPLOYEENO) REFERENCES EMPLOYEE,
CHECK (('0' <= SUBSTR(AREA_CODE,1,1) AND SUBSTR(AREA_CODE,1,1) <= '9')
AND ('0' <= SUBSTR(AREA_CODE,2,1) AND SUBSTR(AREA_CODE,2,1) <= '9')
AND ('0' <= SUBSTR(AREA_CODE,3,1) AND SUBSTR(AREA_CODE,3,1) <= '9')),
CHECK (('0' <= SUBSTR(NUMBER,1,1) AND SUBSTR(NUMBER,1,1) <= '9')
AND ('0' <= SUBSTR(NUMBER,2,1) AND SUBSTR(NUMBER,2,1) <= '9')
AND ('0' <= SUBSTR(NUMBER,3,1) AND SUBSTR(NUMBER,3,1) <= '9')
AND ('0' <= SUBSTR(NUMBER,4,1) AND SUBSTR(NUMBER,4,1) <= '9')
AND ('0' <= SUBSTR(NUMBER,5,1) AND SUBSTR(NUMBER,5,1) <= '9')
AND ('0' <= SUBSTR(NUMBER,6,1) AND SUBSTR(NUMBER,6,1) <= '9'))
)
CREATE TABLE HASNAME (
EMPLOYEENO CHAR(6) NOT NULL,
FIRST VARCHAR(10) NOT NULL,
MIDDLE VARCHAR(10),
LAST VARCHAR(20) NOT NULL,
PRIMARY KEY (EMPLOYEENO,FIRST,LAST), FOREIGN
KEY (EMPLOYEENO) REFERENCES EMPLOYEE
)
CREATE TABLE HASADDRESS (
EMPLOYEENO CHAR(6) NOT NULL,
STRNO VARCHAR(6) NOT NULL,
STREET VARCHAR(20) NOT NULL,
Sample Queries
Query 1: give all employee_no for all the workers that work under manager with the
first name Tony7 and the last name Tona7 with no middle name.
SELECT WORKER.EMPLOYEENO
FROM WORKER,
(SELECT MANAGER.EMPLOYEENO FROM MANAGER,HASNAME
WHERE MANAGER.EMPLOYEENO=HASNAME.EMPLOYEENO
AND HASNAME.FIRST='TONY7' AND HASNAME.MIDDLE IS NULL
AND HASNAME.LAST='TONA7') AS T
WHERE WORKER.MANAGERNO=T.EMPLOYEENO
Query 2: give all the names and employee_no for all the workers the names should
be listed in an alphabetic order (by last, then by first, then by middle)
SELECT WORKER.EMPLOYEENO,FIRST,MIDDLE,LAST ROM WORKER,HASNAME
WHERE WORKER.EMPLOYEENO=HASNAME.EMPLOYEENO
ORDER BY LAST, FIRST, MIDDLE
Query 3: give all the phones and employee_no for all the managers.
SELECT MANAGER.EMPLOYEENO,AREA_CODE,NUMBER
FROM MANAGER,HASPHONE
WHERE MANAGER.EMPLOYEENO=HASPHONE.EMPLOYEENO
Query 4: list all parts that are assemblies they should be listed in a lexicographic order.
SELECT DISTINCT ASSEMBLYNO FROM SUBPART ORDER BY ASSEMBLYNO
Query 5: for each manager, list all current backorders done by the manager.
SELECT MANAGER.EMPLOYEENO,PARTNO,ORIG_QUANTITY,REMAINING_QUANTITY,
BO_DATE, BACKORDERED_BY
FROM MANAGER,CURRENT_BACKORDER
WHERE MANAGER.EMPLOYEENO=CURRENT_BACKORDER.BACKORDERED_BY
Query 6: For each manager, list all current and old backorders done by the manager.
For each backorder you have to list the part_no, backorder date, and fulfilled
date. For current backorders, list a phony fulfilled date '2000-01-01'.
Query 7: For each warehouse bin, give the remaining capacity of the bin. Call the remaining
capacity remaining_capacity.
Query 8: Give employee_no and number of workers managed for all the managers
with The smallest number of workers managed.
SELECT MANAGERNO, NUMBER_MANAGED
FROM (SELECT MANAGERNO,COUNT(*) AS NUMBER_MANAGED
FROM WORKER GROUP BY MANAGERNO) AS T1
EXCEPT
SELECT T1.MANAGERNO, T1.NUMBER_MANAGED
FROM (SELECT MANAGERNO,COUNT(*) AS NUMBER_MANAGED
FROM WORKER GROUP BY MANAGERNO) AS T1, (SELECT
MANAGERNO,COUNT(*) AS NUMBER_MANAGED FROM
WORKER GROUP BY MANAGERNO) AS T2
WHERE T1.NUMBER_MANAGED > T2.NUMBER_MANAGED