Team LiB   Previous Section   Next Section

2.16 Finding Complements of Sets with Different Universes

2.16.1 Problem

You want to write a query that returns the complement of several sets, but each of those sets has a different universe. For example, consider that different courses each require a different number of term papers. You want to list the papers that are missing for each student in each course. Unlike the queries in the previous recipes, this query must correctly handle the different term paper requirements (the universe) of each course.

2.16.2 Solution

You first need a master table to record the number of term papers required for each course:

CREATE TABLE CourseMaster(
   CourseId CHAR(20),
   numTermPapers INTEGER
)

After creating the CourseMaster table, you need to populate it with data. The following two INSERTs specify that the ACCN101 course requires four term papers and that the MGMT120 course requires three term papers:

INSERT INTO CourseMaster VALUES('ACCN101',4)
INSERT INTO CourseMaster VALUES('MGMT120',3)

With the CourseMaster table created and populated, you can use the following query to report on term papers that have not yet been submitted:

SELECT  s.StudentName, s.CourseId, f.i TermPaper
FROM Students s, Pivot f, CourseMaster c
WHERE f.i BETWEEN 1 AND c.numTermPapers 
   AND c.CourseId=s.CourseId 
GROUP BY s.StudentName, s.CourseId, f.i
HAVING NOT EXISTS(
   SELECT * FROM Students 
   WHERE CourseId=s.CourseId AND 
      StudentName=s.StudentName AND 
      TermPaper=f.i)
ORDER BY s.StudentName

The result is a list of term papers that each student still needs to submit to pass a given course:

StudentName  CourseId  TermPaper   
------------ --------- ---------- 
Andrew       ACCN101   1
Bert         ACCN101   4
Cindy        ACCN101   3
Cindy        ACCN101   4

2.16.3 Discussion

This query is almost identical to the query presented in the earlier recipe titled "Finding the Complement of a Set." The major difference is how term paper requirements are specified. In the previous recipe, the number of term papers for each course was the same, and that value was represented by a constant:

WHERE f.i BETWEEN 1 AND 4 

For this recipe, each course has a different requirement. That requirement has to be recorded somewhere, and that's where the CourseMaster table comes into play. The first part of the query is then modified as follows:

SELECT  s.StudentName, s.CourseId, f.i TermPaper
FROM Students s, Pivot f, CourseMaster c
WHERE f.i BETWEEN 1 AND c.numTermPapers
  AND c.CourseId = s.CourseId
...

The CourseMaster table is joined to the Students table based on the CourseId column, thus giving us access to the numTermPapers column. That column contains the course-specific requirement for the number of term papers and replaces the constant used in the earlier version of the query.

    Team LiB   Previous Section   Next Section