You are on page 1of 5

Assignment 2a: Aggregates and grouping, and ordering

The following questions are all based on the university schema. For your reference a copy of the schema
diagram is available here.

1. Find the number of instructors who have never taught any course. If the result of your query is 0,
add appropriate data (and include corresponding insert statements) to ensure the result is not 0.
Sol: select count(*) 
from instructor 
where ID not in (select ID from teaches);

2. Find the total capacity of each of the buildings in the university.


Sol: select building, sum(capacity) 
from classroom 
group by building;

3. Find the maximum number of teachers for any single course section.
Hint: Use a subquery in the from clause, or use the with clause.
Sol: with count_teachers (num) as
(select count(ID) as num 
from teaches 
group by course_id, sec_id, semester, year)
select max(num) 
from count_teachers;

4. Find all departments that have the minimum number of instructors, using a subquery; order the
result by department name in descending order. 
Sol: with count_num(dept_name, num) as
(select dept_name, count(*) as num 
from instructor group by dept_name)
select * from count_num 
where num = (select min(num) from count_num)
order by dept_name desc;

5. For each student, compute the total credits they have successfully completed, i.e. total credits of
courses they have taken, for which they have a non-null grade other than 'F'. Do NOT use the
tot_creds attribute of student.
Sol: select student.ID, name, sum(course.credits) 
from takes, student, course 
where grade <> 'F' 
and grade is not null 
and takes.course_id = course.course_id 
and student.ID = takes.ID 
group by student.ID, name;

6. Find the number of students who have been taught (at any time) by an instructor named
'Srinivasan'. Make sure you count a student only once even if the student has taken more than one
course from Srinivasan.
Note: If you use the join clause, we suggest you use the join ..using (..) clause, since attribute
names such as ID are repeated in teaches and takes, which would be wrongly equated if you
use natural join. 
Sol: select count(distinct takes.ID) 
from instructor, takes, teaches
where takes.course_id = teaches.course_id 
and takes.sec_id = teaches.sec_id 
and takes.semester = teaches.semester 
and takes.year = teaches.year 
and teaches.ID=instructor.ID 
and instructor.name='Srinivasan';

7. Find the name of all instructors who get the highest salary in their department.
Hint: Use a subquery in the where clause to find the highest salary in the department of an
instructor, or use a subquery in the from clause to find highest salaries in each department.
Sol: select name from instructor I1 , 
(select max(salary) as maxsal,dept_name 
from instructor 
group by dept_name ) I2 
where (I2.maxsal = I1.salary and I1.dept_name = I2.dept_name )

8. Find all students who have taken all courses taken by instructor 'Srinivasan'. (This is the division
operation of relational algebra.) 
As with other division operation queries, you can implement it by using a subquery of the
form not exists(SQ1 except SQ2); in this case SQ1 and SQ2 find courses taught by Srinivasan,
and courses taken by the student. 
There are other ways to implement the query, for example by counting the number of distinct
courses taught by Srinivasan, and counting the number of distinct courses taken by each student
that were taught by Srinivasan (your query would group by student.ID); these two subqueries can
be combined to select those where the counts match.
Sol: select distinct S.ID,name 
from takes as S, student 
where S.ID = student.ID and not exists 
( (select course_id from teaches,instructor 
where instructor.ID=teaches.ID and instructor.name='Srinivasan') 
except 
(select course_id from takes as T where student.ID = T.ID ));

9. Find the total money spent by each department for salaries of instructors of that department. (a)
First write the query ignoring the case of departments with no instructor, and the (b) modify your
query to ensure departments with no instructors are output with a value of 0.
Sol: select dept_name, sum(salary) 
from instructor
group by dept_name;

To handle the case of departments with no instructors, we can either use a


subquery, or use a left-outer join operation. The version with a subquery is:

select department.dept_name, 
(select (case 
when sum(salary) is not null then sum(salary)
else 0 end)
as total_salary
from instructor 
where instructor.dept_name = department.dept_name)
from department;

Note that the subquery returns null if there are no instructors in the
department, and we have to make sure to get a 0 value in this case. 
SQL also supports a function called coalesce which returns the first non-null
value in a list, which can be used to write the query as

select department.dept_name, 
(select coalesce(sum(salary), 0) as total_salary
from instructor
where instructor.dept_name = department.dept_name)
from department;

If we use outerjoin, the corresponding query would be 


select department.dept_name, 
coalesce(sum(salary), 0) as total_salary
from department natural left outer join instructor
group by department.dept_name;

10. (Optional) List out the names of all Students whose advisor teaches maximum no of subjects.
(Hint: we suggest you structure the query using a with clause.)
Sol: with max_sub(val) as
(select max(no_of_subjects) as val 
from (select count(teaches.course_id) as no_of_subjects 
from teaches 
group by teaches.id)),
max_instructors(inst_id) as
(select id from instructor 
where (select count(teaches.course_id) as no_of_subjects 
from teaches 
where teaches.id = instructor.id 
group by teaches.id) = (select val from max_sub))
select name from student natural join advisor 
where advisor.i_id in (select inst_id from max_instructors)

Expected results for Assignment 2a: 

1. count 
-------
3
(1 row)

2. building | sum 
----------+-----
Painter | 10
Taylor | 70
Packard | 500
Watson | 80
(4 rows)
3. max 
-----
1
(1 row)
4. dept_name | num 
------------+-----
Elec. Eng. | 1
Music | 1
Biology | 1
(3 rows)
5. id | name | sum 
-------+----------+-----
98765 | Bourikas | 7
76543 | Brown | 7
98988 | Tanaka | 4
19991 | Brandt | 3
12345 | Shankar | 14
55739 | Sanchez | 3
45678 | Levy | 7
23121 | Chavez | 3
76653 | Aoi | 3
44553 | Peltier | 4
00128 | Zhang | 7
54321 | Williams | 8
(12 rows)
6. count 
-------
6
(1 row)
7. name 
-----------
Wu
Mozart
Einstein
Califieri
Crick
Brandt
Kim
(7 rows)
8. id | name 
-------+---------
12345 | Shankar
(1 row)
9. dept_name | sum 
------------+-----------
Comp. Sci. | 232000.00
Elec. Eng. | 80000.00
Physics | 182000.00
Biology | 72000.00
History | 122000.00
Music | 40000.00
Finance | 170000.00
(7 rows)
10. name 
----------
Zhang
Shankar
Brandt
Chavez
Peltier
Levy
Williams
Sanchez
Snow
Brown
Aoi
Bourikas
Tanaka
(13 rows)

You might also like