CSC424 Lab 3 Emile C. Chi Access 2.0 Win3.11 Nov 1997

advertisement
CSC715 Lab 2
Emile C. Chi
MySQL
Fall 2014
1) make a list of all the departments in the university. Note that some
departments may have profs but no students, courses but no profs, etc
SELECT distinct dept
FROM prof
UNION
SELECT distinct dept
FROM student
UNION
SELECT distinct dept
FROM course
FORDER BY dept;
dept
CC
CS
EALC
ENG
ENGL
GOVT
MATH
MUS
PE
RUSS
2) How many departments are there in the university?
CREATE VIEW dept_list(dept) AS
SELECT dept
FROM prof
UNION
SELECT dept
FROM student
UNION
SELECT dept
FROM course
Then run this:
SELECT COUNT(dept) AS Num_Depts
FROM Dept_List;
Num_Depts
10
3) Find all departments in which the average salary is higher (lower) than the
average salary in the GOVT dept
First create these views:
CREATE VIEW Avg_Sal_GOVT (Avg_Sal_GOVT) AS
SELECT avg(Salary) AS Avg_Sal_GOVT
FROM prof
WHERE dept = 'GOVT';
CREATE VIEW Avg_Sal(dept,Avg_Sal) AS
SELECT dept, avg(Salary)AS Avg_Sal
FROM prof
GROUP BY dept;
Check the views:
SELECT *
FROM Avg_Sal_GOVT;
Avg_Sal_GOVT
$146,500.00
SELECT *
FROM Avg_Sal;
dept
Avg_Sal
CC
10000.540000
MATH 50004.935000
CS
116501.060000
GOVT 146500.000000
Then run any of these:
SELECT dept, Avg_Sal
FROM Avg_Sal
WHERE AVG_Sal <
(SELECT Avg_Sal
FROM
Avg_Sal
WHERE dept = 'GOVT');
SELECT dept, Avg_Sal
FROM Avg_Sal
WHERE AVG_Sal <
(SELECT Avg_Sal_GOVT
FROM Avg_Sal_GOVT);
SELECT dept, avg(Salary) AS Avg_Sal
FROM prof
GROUP BY dept
HAVING AVG(Salary) <
(SELECT AVG(Salary)
FROM prof
WHERE dept = 'GOVT');
dept
Avg_Sal
CC
10000.540000
CS
116501.060000
MATH 50004.935000
4) How many grades of ‘F' were given in each section? Retrieve the secnum, the
term and the number of F’s.
SELECT secnum, term, COUNT(grade) AS F_Grades
FROM report
GROUP BY secnum, term, grade
HAVING grade = 'F'
ORDER BY term;
secnum term F_Grades
8765
F08 1
4190
F09 1
8765
F11 1
2804
F35 1
1234
S02 1
2804
S03 1
2804
S04 1
9023
S07 1
7777
S08 1
4937
S08 1
5) List the names of all students who got a ‘D’ or an ‘F’ in a course.
Retrieve the student’s last name, the cnum of the course and the term and
secnum of the section in which she/he got the bad grade and the grade
SELECT st.snum, st.lastname, s.cnum, s.secnum, s.term, r.grade
FROM student AS st, section as s, report as r
WHERE st.snum = r.snum
AND (r.grade = 'D' OR r.grade = 'F')
/* why are the
parentheses necessary here? */
AND s.secnum = r.secnum
AND s.term = r.term
ORDER BY lastname;
snum
lastname cnum
secnum term grade
777777777 Belaief
CSC424 4190
F09 F
777777777 Belaief
CSC231 7777
S08 F
115327466 Bush
GOV100 2804
F35 F
456587847 Mao
CSC330 1234
S02 F
456587847 Mao
GOV100 2804
S04 F
Note: The following program gives an erroneous answer with more students
because it ignores the bad or missing data in the section and report tables. e.g.
there is no secnum = ‘8765’ in the section table but there are many in the report
table (in various terms) so student Clinton is shown getting an F in section 8765
F11, which does not exist (in any term)!
SELECT st.snum, st.lastname
FROM student AS st
WHERE st.snum in
(SELECT snum
FROM report r
WHERE grade > r.grade = 'D' OR r.grade = 'F';
snum
lastname secnum term grade
345098765 Ali
8765
F08 F
345098765 Ali
8765
F11 D
777777777 Belaief
4190
F09 F
777777777 Belaief
7777
S08 F
115327466 Bush
2804
F35 F
987654321 Clinton 8765
F11 F
456587847 Mao
1234
S02 F
456587847 Mao
2804
S03 F
456587847 Mao
2804
S04 F
6) Find all departments with more professors than students
First create these views:
CREATE VIEW numstu(dept,numstu) AS
SELECT dept, count(*) AS numstu
FROM student
GROUP BY dept;
CREATE VIEW numprof(dept,numprof) AS
SELECT dept, count(*) AS numprof
FROM prof
GROUP BY dept;
Query the views:
select * from numstu;
Dept
Numstu
CS
3
ENG
1
ENGL
2
GOVT
5
MATH
1
MUS
1
PE
1
RUSS
1
select * from numprof;
dept
numprof
CC
1
CS
5
GOVT 2
MATH 2
Now:
SELECT DISTINCT sd.dept
FROM
Numstu AS sd, Numprof AS pd
WHERE
AND
(pd.dept = sd.dept
pd.numprof > sd.numstu);
Dept
CS
MATH
This program also works:
SELECT dept
FROM prof p
GROUP BY dept
HAVING count(pnum) > ANY
(SELECT count(snum)
FROM student
GROUP BY dept
HAVING p.dept = dept);
Note that this program becomes more difficult if we ask: Find all
departments with more students than professors: Why?
SELECT DISTINCT sd.dept
FROM Numstu AS sd, Numprof AS pd
WHERE pd.dept = sd.dept
AND pd.numprof < sd.numstu
OR
sd.dept NOT IN (SELECT dept
FROM
SELECT dept
FROM prof p
GROUP BY dept
HAVING count(pnum) < ANY
(SELECT count(snum)
FROM student
GROUP BY dept
HAVING p.dept = dept)
UNION
SELECT dept
FROM student
WHERE dept NOT IN (SELECT dept
FROM
Dept
ENG
ENGL
GOVT
MUS
prof);
prof);
PE
RUSS
select dept
/* here we get the correct answer w/o checking
for depts. With 0 profs separately */
from student st
group by st.dept
having count(st.snum) >(select count(p.pnum)
from prof p
where st.dept = p.dept);
This answer is logically incorrect:
And it gives the wrong answer!
WHY???
select dept
from prof
group by dept
having count(pnum) < any (select count(snum)
from student
group by dept)
UNION
select dept
from student
where dept not in (select dept
from prof);
7) Find the id’s and last names all of the students who have never passed any
course. This must include all students who never took a course.
select snum,lastname
from student
where snum not in
(select snum
from report
where grade < 'F' and grade <> ' ')
passing grades */
ORDER BY lastname;
snum
lastname
115327466 Bush
020187673 Hu
456587847 Mao
123456789 Mutai
058938586 Obama
444555666 Radcliffe
/* 'F', 'W' and ' ' are not
555555555 Springer
684903033 Zhao
8) Find the names of all students who have taken a MATH course
SELECT st.snum, st.lastname
FROM student st
WHERE EXISTS
(select *
from course c
where c.dept = 'MATH'
and EXISTS
(select *
from section s
where c.cnum = s.cnum
and EXISTS
(SELECT *
FROM report r
WHERE st.snum = r.snum
and s.secnum = r.secnum
and s.term = r.term)));
Snum lastname
This answer is not so satisfactory, as it is null, so let’s run the program for
students who have taken a CS course:
SELECT st.snum, st.lastname
FROM student st
WHERE EXISTS
(select *
from course c
where c.dept = 'CS'
and EXISTS
(select *
from section s
where c.cnum = s.cnum
and EXISTS
(SELECT *
FROM report r
WHERE st.snum = r.snum
and s.secnum = r.secnum
and s.term = r.term)));
Snum
lastname
019385842 Pierce
020187673 Hu
111222333 Belaief
123456789 Mutai
345098765 Ali
456587847 Mao
555555555 Springer
777777777 Belaief
798783733 Lincoln
987654321 Clinton
select distinct t.snum, t.lastname
*/
from student t, course c, section s, report r
where c.cnum = s.cnum
and c.dept ='CS'
and t.snum = r.snum
and s.secnum = r.secnum
and s.term = r.term;
/* This also works
Download