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