Proposed solutions Project Assignment #1 (SQL) (a) Database creation: create table sailor (sname CHAR(30), rating INTEGER) create table boat (bname CHAR (30), color CHAR (15), rating INTEGER) create table reservation (sname CHAR(30), bname CHAR (30), rday CHAR(15), starting INTEGER, ending INTEGER) (b) Instance upload: insert into sailor values ( Brutus, 1); insert into sailor values ( Andy, 8); insert into sailor values ( Horatio, 7); insert into sailor values ( Rusty, 8); insert into sailor values ( Bob, 1); insert into boat values ( SpeedQueen, white, 9); insert into boat values ( InterLake, red, 8); insert into boat values ( Marine, blue, 7); insert into boat values ( Bay, red, 3); values ( Andy, Interlake, Monday, 10, 14); values ( Andy, Marine, Saturday, 14, 16); values ( Andy, Bay, Wednesday, 8, 12); values ( Rusty, Bay, Sunday, 9, 12); values ( Rusty, Interlake, Wednesday, 13, 20); values ( Rusty, Interlake, Monday, 9, 11); values ( Andy, Bay, Wednesday, 9, 10); values ( Horatio, Marine, Tuesday, 16, 19); 1
(c) Instance listing: select * from sailor; select* from boat; select * ; (d) SQL queries: 1., bname from sailor, boat where sailor.rating >= boat.rating 2., count(bname) as number from sailor, boat where sailor.rating >= boat.rating group by sname) union, 0 as number from sailor from sailor, boat where sailor.rating boat.rating)) Note that Brutus and Bob are not qualified to sail any boat, so their count should be shown as zero. 3. (i) one using the MIN aggregate function, and from sailor where rating in (select MIN(rating) from sailor) 2
(ii) another without using MIN. select s.sname from sailor s from sailor where rating < s.rating) 4., boat where reservation.bname = boat.bname and boat.color <> red ) Without the assumption that each boat has only one color, we would write: where bname not in (select bname from boat where color = red )) 5. select s.sname from sailor s r, boat b where r.sname = s.sname and r.bname = b.bname and color = red ) Note that Brutus is one of these since he has no reservations. 3
6. (i) with NOT IN tests;, boat b where b.color = red and sname not in where bname = b.bname )) (ii) with NOT EXISTS tests; select r.sname r from boat b where b.color = red and not exists where sname = r.sname and reservation.bname = b.bname )) (iii) with COUNT aggregate functions. select r.sname r where (select count(*) from boat b where b.color = red and ( select count(*) where sname = r.sname and bname = b.bname) = 0 ) = 0 4
alternatively, select r.sname r, boat b where r.bname = b.bname and b.color = red group by r.sname having count (distinct r.bname) = (select count (distinct bname) from boat where color = red ) 7. create view unique as select distinct sailor.sname, rating, bname from sailor, reservation where sailor.sname = reservation.sname; select bname, avgrating = avg(rating * 1.0) from unique group by bname The reason for multiplying rating with 1.0 in avg(rating * 1.0) is to convert the rating to a real so that the average is not truncated to an integer. The role of the view unique is to provide the list of boats and sailors with their ratings who have reserved the boatwithout duplicates. This is to avoid counting the same sailor multiple times if the sailor has multiple reservations of the same boat. For example, the following alternative does not avoid this problem: select bname, avgrating = avg(rating) from sailor, reservation where sailor.sname = reservation.sname group by bname 5
(e) select x.bname, x.rday, x.sname as sname1, x.starting as start1, x.ending as end1, y.sname as sname2, y.starting as start2, y.ending as end2 x, reservation y where x.bname = y.bname and x.rday = y.rday and ((x.starting = y.starting and x.ending = y.ending and x.sname < y.sname) or (x.starting = y.starting and x.ending > y.ending) or (x.starting < y.starting and y.starting < x.ending)) Note that this lists only one tuple for every pair of conflicting reservations x, y. Indeed, suppose first the time intervals of the reservations are the same. Then the sailors of the two reservations should be different (otherwise x and y would be the same reservation). The double listing is avoided by requiring that x.sname < y.sname (this compares the strings). If the starting time of the two reservations are the same and the intervals are not equal then only one of them ends first, so requiring x.ending > y.ending avoids again the double listing. Finally, if the reservations have different starting times then only one starts first, so x.starting < y.starting avoids double listing. (f) Updates in SQL. 1. update boat set color = xxx where color = blue ; update boat set color = blue where color = red ; update boat set color = red where color = xxx 2. delete from sailor s from boat where s.rating boat.rating) 6