term and then course name (both of which should also be ...cs348/w10/assignments/a1s… · 1. print...

20
1. Print a list of student numbers, student names, and final grades for each past class taught by Smith, ordered by term and then course name (both of which should also be printed in the list). select m.term, cname, s.snum, sname, grade from student s, mark m, course c, class cl, professor p where s.snum = m.snum and m.cnum = cl.cnum and m.term = cl.term and m.section = cl.section and cl.cnum = c.cnum and cl.pnum = p.pnum and pname= 'Smith' order by m.term, cname /* joining with the enrollment relation as well is useless, but OK (non-null foreign keys are already included in the join conditions), but joining with the schedule relation might lose tuples */ or with m(snum,cnum,term,section,grade,year,oterm) as (select snum,cnum,term,section,grade, substr(term,2,2), case when substr(term,1,1)='W' then 1 when substr(term,1,1)='S' then 2 else 3 end from mark) select m.term, cname, s.snum, sname, grade from student s, m, course c, class cl, professor p ... order by m.year, m.oterm, cname

Upload: others

Post on 05-Oct-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: term and then course name (both of which should also be ...cs348/W10/assignments/A1S… · 1. Print a list of student numbers, student names, and final grades for each past class

1. Print a list of student numbers, student names, and final grades for each past class taught by Smith, ordered by

term and then course name (both of which should also be printed in the list).

select m.term, cname, s.snum, sname, grade

from student s, mark m, course c, class cl, professor p

where s.snum = m.snum

and m.cnum = cl.cnum and m.term = cl.term

and m.section = cl.section

and cl.cnum = c.cnum

and cl.pnum = p.pnum and pname= 'Smith'

order by m.term, cname

/* joining with the enrollment relation as well is useless, but OK (non-null foreign keys are already included in the

join conditions), but joining with the schedule relation might lose tuples */

or

with m(snum,cnum,term,section,grade,year,oterm) as

(select snum,cnum,term,section,grade, substr(term,2,2),

case when substr(term,1,1)='W' then 1

when substr(term,1,1)='S' then 2

else 3 end

from mark)

select m.term, cname, s.snum, sname, grade

from student s, m, course c, class cl, professor p

...

order by m.year, m.oterm, cname

Page 2: term and then course name (both of which should also be ...cs348/W10/assignments/A1S… · 1. Print a list of student numbers, student names, and final grades for each past class

2. How many students have received a mark in CS246?

select count (distinct snum)

from mark

where cnum = 'CS246'

/* it is unstated whether we want to include repetitions in the count */

Page 3: term and then course name (both of which should also be ...cs348/W10/assignments/A1S… · 1. Print a list of student numbers, student names, and final grades for each past class

3. Give the course data for a student transcript showing the course number, term, and grade (if completed) for

each course taken by the student whose number is 4321, ordered by term. Show the value -1 for courses in

progress.

select e.cnum, e.term, case when grade is null then -1 else grade end

from enrollment e left outer join mark m on (e.snum = m.snum

and e.cnum = m.cnum and e.term = m.term

and e.section = m.section)

where e.snum = 4321

order by e.term

Page 4: term and then course name (both of which should also be ...cs348/W10/assignments/A1S… · 1. Print a list of student numbers, student names, and final grades for each past class

4. List the course numbers for courses that were taught at some time but not taught in W07.

select cnum

from class

except

select cnum

from class

where term = 'W07'

/* alternatively, "taught at some time" implies presence in the enrollment relation (if assigned courses are not

necessarily "taught") -- in this case, use enrollment for both selects, rather than class */

Page 5: term and then course name (both of which should also be ...cs348/W10/assignments/A1S… · 1. Print a list of student numbers, student names, and final grades for each past class

5. Give a list of rooms that are used in W07 fewer than 3 times on Mondays or more than twice on Tuesdays.

select room

from schedule

where term = 'W07'

group by room, day

having (day = 'Monday' and count(*) < 3)

or (day = 'Tuesday' and count(*) > 2)

union

(select room

from schedule

where term = 'W07'

except

select room

from schedule

where term = 'W07'

group by room, day

having day = 'Monday')

/* the "except" part of union gives rooms not used at all on Mondays in W07, but it assumes that the query is

asking for rooms used at least once in W07; otherwise remove where clause from middle select statement; the

query could also be done by first forming a count for all rooms in W07: select room, day, count(*) as cnt

from schedule

where term = 'W07'

group by room, day

and then selecting from that based on the criteria */

Page 6: term and then course name (both of which should also be ...cs348/W10/assignments/A1S… · 1. Print a list of student numbers, student names, and final grades for each past class

6. What was the average grade in the section of any past course when someone named Lee was enrolled in that

section?

select m.cnum, m.term, m.section, avg(grade) as average

from mark m,

(select distinct cnum, term, section

from student s, mark m

where sname = 'Lee'

and s.snum = m.snum) lee

where m.cnum = lee.cnum and m.term = lee.term

and m.section = lee.section

group by m.cnum, m.term, m.section

/* distinct is not strictly needed in the nested select, since we're grouping on all three values and repeating all

entries an equal number of times does not change the average */

Page 7: term and then course name (both of which should also be ...cs348/W10/assignments/A1S… · 1. Print a list of student numbers, student names, and final grades for each past class

7. What are the names of professors who have taught the most number of distinct courses, and how many courses

did they teach?

with taught(pname,cnt) as

(select pname, count(*)

from (select distinct p.pnum, pname, cnum

from professor p, class c

where p.pnum = c.pnum) as pclass

group by pnum, pname)

select *

from taught

where cnt = (select max(cnt) from taught)

/* must include pnum when grouping, in case profs' names repeat */

Page 8: term and then course name (both of which should also be ...cs348/W10/assignments/A1S… · 1. Print a list of student numbers, student names, and final grades for each past class

8. Which third year students have taken all CO courses but have not enrolled in any CS classes?

select snum, sname

from student s

where snum not in

(select snum

from enrollment

where cnum like 'CS%')

and year = 3

and not exists

(select cnum

from course

where cnum like 'CO%'

except

select cnum

from enrollment

where enrollment.snum = s.snum)

/* the last part encodes relational divide */

Page 9: term and then course name (both of which should also be ...cs348/W10/assignments/A1S… · 1. Print a list of student numbers, student names, and final grades for each past class

9. Which courses have had more sections offered on Mondays and Wednesdays than on Tuesday and Thursdays?

select mw.cnum

from (select m.cnum, count(*) as cnt

from (select cnum, term, section

from schedule

where day = 'Monday') m,

(select cnum, term, section

from schedule

where day = 'Wednesday') w

where m.cnum = w.cnum and m.term = w.term

and m.section = w.section

group by m.cnum) as mw

left outer join

(select t.cnum, count(*) as cnt

from (select cnum, term, section

from schedule

where day = 'Tuesday') t,

(select cnum, term, section

from schedule

where day = 'Thursday') r

where t.cnum = r.cnum and t.term = r.term

and t.section = r.section

group by t.cnum) as tr

on mw.cnum = tr.cnum

where mw.cnt > tr.cnt or tr.cnt is null

/* left outer join and test for null catches courses not offered on T/Th */

Page 10: term and then course name (both of which should also be ...cs348/W10/assignments/A1S… · 1. Print a list of student numbers, student names, and final grades for each past class

10. Print a list of student numbers, student names, and cumulative average grades in decreasing order of average

grade for all students who have taken at least three courses and have a cumulative average over 85.

select s.snum, s.sname, avg(grade) as grd

from student s, mark m

where s.snum = m.snum

group by s.snum, s.sname

having count(*) >= 3 and avg(grade) > 85

order by grd desc

Page 11: term and then course name (both of which should also be ...cs348/W10/assignments/A1S… · 1. Print a list of student numbers, student names, and final grades for each past class

11. Print a list of student numbers, student names, and final grades for each past class taught by Smith.

Page 12: term and then course name (both of which should also be ...cs348/W10/assignments/A1S… · 1. Print a list of student numbers, student names, and final grades for each past class

12. Which students (snum, sname, and year) received a mark in CS246 and a mark in CS 240?

Page 13: term and then course name (both of which should also be ...cs348/W10/assignments/A1S… · 1. Print a list of student numbers, student names, and final grades for each past class

13. Assuming that the relation Minus1 has a single attribute named val and a single tuple with value -1, give the

course data for a student transcript showing the course number, term, and grade (if completed) of each course taken

by the student whose student number is 4321. Show the value -1 for courses in progress.

Page 14: term and then course name (both of which should also be ...cs348/W10/assignments/A1S… · 1. Print a list of student numbers, student names, and final grades for each past class

14. List the course numbers for courses that were taught at some time but not taught in W07.

Page 15: term and then course name (both of which should also be ...cs348/W10/assignments/A1S… · 1. Print a list of student numbers, student names, and final grades for each past class

15. Which third year students have taken all classes offered by Smith but have not enrolled in any classes offered

by Jones?

Page 16: term and then course name (both of which should also be ...cs348/W10/assignments/A1S… · 1. Print a list of student numbers, student names, and final grades for each past class

16. Translate the following E-R diagram into a relational schema that will not require the use of null values,

illustrated by a diagram in the style used for Parts 1 and 2.

Note that Owns.pname cannot be a foreign key, since Publisher.pname is not a primary key.

Illustrator, Manuscript, and Book must be separate relations from Work to avoid need for nulls.

cid title

Work

pages royalties

pname city

Publisher

cid

Contributor

name city

cid title

Manuscript

acqDate status

cid title

Book

pubDate price

pname cid title

Owns

cid title

Illustrator

illus_cid fee

Page 17: term and then course name (both of which should also be ...cs348/W10/assignments/A1S… · 1. Print a list of student numbers, student names, and final grades for each past class

17. List any constraints present in the E-R diagram that are not captured by the relational schema diagram.

Every work is owned by at most 2 publishers.

Every work is either a book or a manuscript, but not both.

Optional assumption: every publisher is in at least one city => need an additional constraint that every

publisher in Owns also appears in Publisher.

Page 18: term and then course name (both of which should also be ...cs348/W10/assignments/A1S… · 1. Print a list of student numbers, student names, and final grades for each past class

18. Give SQL DDL statements for creating each of the tables in your diagram. Be sure to include all the

constraints. (You’ll need to choose suitable domains for the attributes.)

create table publisher (

pname varchar(50) not null,

city varchar(20) not null,

primary key (pname,city) )

create table contributor (

cid int not null primary key,

name varchar(40),

city varchar(20) )

create table work (

cid int not null

references contributor,

title varchar(50) not null,

pages int,

royalties decimal(9,2),

primary key (cid,title) )

create table illustrator (

cid int not null,

title varchar(50) not null,

illus_cid int not null

references contributor(cid),

fee decimal(9,2),

primary key (cid,title),

foreign key (cid,title)

references work )

create table manuscript (

cid int not null,

title varchar(50) not null,

acqDate date,

status char(3),

primary key (cid,title),

foreign key (cid,title) references work )

create table book (

cid int not null,

title varchar(50) not null,

pubDate date,

price decimal(5,2),

primary key (cid,title),

foreign key (cid,title) references work )

create table owns (

pname varchar(50) not null,

cid int not null,

title varchar(50) not null,

primary key (pname,cid,title),

foreign key (cid,title)

references work,

constraint onlyTwo

check (2 >= (select count(pname)

from owns

where cid = n.cid

and title = n.title)) )

Page 19: term and then course name (both of which should also be ...cs348/W10/assignments/A1S… · 1. Print a list of student numbers, student names, and final grades for each past class

Since DB2 does not permit select in check constraints, could instead use a trigger to enforce it:

create trigger twoPublishers

no cascade before insert on owns

referencing new as n

for each row mode db2sql

when ( (select count(pname)

from owns

where cid = n.cid and title = n.title) = 2 )

signal sqlstate '34801'

('No more than two publishers can own a work')

In some SQL implementations, could use an assertion for the second constraint:

Create assertion coversWork

Check (not exists (

(select cid, title from work

except select cid, title from manuscript)

except select cid, title from book )

and not exists (

select cid, title from book

except select cid, title from manuscript )

and not exists (

select cid, title from manuscript

except select cid, title from book )

)

Page 20: term and then course name (both of which should also be ...cs348/W10/assignments/A1S… · 1. Print a list of student numbers, student names, and final grades for each past class

But again DB2 would have to rely on triggers (here, enforcing a certain workflow):

create trigger coversWork0

after insert on work

referencing new as n

for each row mode db2sql

insert into manuscript values

(n.cid,n.title,null,null)

create trigger coversWork1

after insert on book

referencing new as n

for each row mode db2sql

delete from manuscript

where cid=n.cid and title=n.title

create trigger coversWork2

after delete on book

referencing old as o

for each row mode db2sql

delete from work

where cid=o.cid and title=o.title