Skip to content

The Relational Algebra Learning Notes

Updated: at 16:50Suggest Changes

Table of contents

Open Table of contents

Introduction

Relational algebra is a procedural query language that works on relations (tables) and produces relations as a result. It’s a fundamental concept in database theory, providing a theoretical foundation for SQL and other database query languages. It consists of a set of operations that take one or two relations as input and produce a new relation.

Data Operations

1. Students Relation

StudentIDNameMajor
101AliceComputer Sci
102BobMathematics
103CharlieComputer Sci
104DavidPhysics

2. Enrollment Relation

StudentIDCourseIDGrade
101CS101A
101MA101B+
102CS101B
103PH101C
104MA101A-

1. Selection (σ\sigma)

The selection operation selects tuples (rows) from a relation that satisfy a given condition.

2. Projection (Π\Pi)

The projection operation selects specified attributes (columns) from a relation, removing duplicate tuples in the result.

3. Union (\cup)

The union operation combines two relations that have the same number of attributes and compatible domains (schema).

It produces a relation containing all tuples that are in either of the original relations, removing duplicates.

4. Intersection (\cap)

The intersection operation produces a relation containing all tuples that are common to both relations. Both relations must have the same schema.

5. Set Difference (-)

The set difference operation produces a relation containing all tuples that are in the first relation but not in the second relation. Both relations must have the same schema.

6. Cartesian Product (×\times)

Also known as Cross Join, this operation combines every tuple from the first relation with every tuple from the second relation.

If relation R has ‘m’ tuples and S has ‘n’ tuples, the result will have ‘m * n’ tuples. The schema of the result is the concatenation of the schemas of the two relations.

7. Join (\bowtie)

The join operation combines tuples from two relations based on a common attribute or a join condition. The most common type is the Natural Join.


While the natural join (or inner join) only returns tuples that have matches in both relations, outer joins are designed to include tuples that might not have a match in the other relation, filling in NULL values where no match exists.

1. Students Relation

StudentIDNameMajor
101AliceComputer Sci
102BobMathematics
103CharlieComputer Sci
104DavidPhysics
105EveArt

2. Enrollment Relation

StudentIDCourseIDGrade
101CS101A
101MA101B+
102CS101B
103PH101C
104MA101A-
106AR101A
101PH101B-

7a. Left Outer Join (\text{⟕})

The Left Outer Join returns all tuples from the left relation and the matching tuples from the right relation. If a tuple in the left relation has no matching tuple in the right relation, the attributes from the right relation will be filled with NULL values.

7b. Right Outer Join (\text{⟖})

The Right Outer Join returns all tuples from the right relation and the matching tuples from the left relation. If a tuple in the right relation has no matching tuple in the left relation, the attributes from the left relation will be filled with NULL values.

7c. Full Outer Join (\text{⟗})

The Full Outer Join returns all tuples from both the left and right relations. If a tuple in the left relation has no match in the right, or vice versa, the non-matching attributes will be filled with NULL values. It’s essentially the union of a Left Outer Join and a Right Outer Join.

8. Rename (ρ\rho)

The rename operation is used to rename a relation or an attribute within a relation. This is useful for making expressions clearer or for distinguishing between attributes that have the same name in a join.

9. Assignment (\leftarrow or :=:= )

The assignment operation allows you to store the result of a relational algebra expression into a new temporary relation variable. This is not a fundamental operation that produces a new type of result, but rather a way to break down complex queries into smaller, manageable steps and store intermediate results.

10. Division (÷\div)

The division operation is used when you want to find tuples in one relation that are related to all tuples in another relation. It’s often described as finding “A divided by B,” where A is a relation with attributes R1R2R_1 \cup R_2 and B is a relation with attributes R2R_2. The result contains attributes R1R_1 for which the corresponding R2R_2 values exist in A for every tuple in B.

This operation is particularly useful for “for all” type queries, such as “Find students who have taken all required courses.”

The division operation is powerful for specific types of “universal quantification” queries. While not as frequently used directly in SQL as other operations, its logic is crucial for understanding how certain complex SQL queries (often involving nested subqueries with NOT EXISTS or COUNT and GROUP BY) are constructed.

11. Group/Aggregation (G\mathcal{G})

The Group/Aggregation operation (often represented as G\mathcal{G} or gamma) is an extension to basic relational algebra that allows for grouping tuples based on common attribute values and then applying aggregate functions (like COUNT, SUM, AVG, MAX, MIN) to each group. It is crucial for summarizing data.

The Aggregation operator is a powerful tool for generating summary reports and answering analytical questions about the data, forming the basis for GROUP BY and aggregate functions in SQL.

Exercises

Exercise1

For table schemas S(Students), C(Courses) and SC(Student-Course Enrollment):

S#SNAMEAGESEX
1Qiang Li23M
2Li Liu22F
5You Zhang22M
C#CNAMETEACHER
k1C Programming LanguageHua Wang
k5Database PrincipleJun Cheng
k8Compiler PrincipleJun Cheng
S#C#GRADE
1k183
2k185
5k192
2k590
5k584
5k880

(1) Retrieve the Course ID (C#) and Course Name (CNAME) of courses taught by Jun Cheng.

ΠC#, CNAME(σTEACHER = ’Jun Cheng’(C))\Pi_{\text{C\#, CNAME}}(\sigma_{\text{TEACHER = 'Jun Cheng'}}(\text{C}))

(2) Retrieve the Student ID (S#) and Name (SNAME) of male students older than 21.

ΠS#, SNAME(σAGE > 21 ∧ SEX = ’M’(S))\Pi_{\text{S\#, SNAME}}(\sigma_{\text{AGE > 21 ∧ SEX = 'M'}}(\text{S}))

(3) Retrieve the names (SNAME) of students who have taken all courses taught by Jun Cheng.

  1. Find all Course IDs taught by Jun Cheng: R1ΠC#(σTEACHER = ’Jun Cheng’(C))R_1 \leftarrow \Pi_{\text{C\#}}(\sigma_{\text{TEACHER = 'Jun Cheng'}}(\text{C}))
  2. Find all (S#, C#) pairs from enrollment: R2ΠS#, C#(SC)R_2 \leftarrow \Pi_{\text{S\#, C\#}}(\text{SC})
  3. Divide student-course pairs by courses taught by ‘Jun Cheng’ to find S# of students who took all of them: R3R2÷R1R_3 \leftarrow R_2 \div R_1
  4. Join with Students to get their names: ΠSNAME(SR3)\Pi_{\text{SNAME}}(\text{S} \bowtie R_3)

(4) Retrieve the Course IDs (C#) of courses not taken by student Qiang Li.

  1. Find the S# of ‘Qiang Li’: R1ΠS#(σSNAME = ’Qiang Li’(S))R_1 \leftarrow \Pi_{\text{S\#}}(\sigma_{\text{SNAME = 'Qiang Li'}}(\text{S}))
  2. Find Course IDs taken by ‘Qiang Li’: R2ΠC#(SCR1)R_2 \leftarrow \Pi_{\text{C\#}}(\text{SC} \bowtie R_1)
  3. Find all distinct Course IDs available: R3ΠC#(C)R_3 \leftarrow \Pi_{\text{C\#}}(\text{C})
  4. Subtract courses taken by ‘Qiang Li’ from all available courses: R3R2R_3 - R_2

(5) Retrieve the Course IDs (C#) of courses that have been selected by at least two students.

  1. Rename SC to allow self-join and distinguish student IDs: SC1ρSC1(SC)SC_1 \leftarrow \rho_{\text{SC}_{1}}(\text{SC}), SC2ρSC2(S#2,C#2,GRADE2)(SC)SC_2 \leftarrow \rho_{\text{SC}_{2}(\text{S\#}_2, \text{C\#}_2, \text{GRADE}_2)}(\text{SC})
  2. Join SC_1 and SC_2 on matching C# but different S#: ΠC#(σSC1.C#=SC2.C# ∧ SC1.S#SC2.S#(SC1×SC2))\Pi_{\text{C\#}}(\sigma_{\text{SC}_1.\text{C\#} = \text{SC}_2.\text{C\#} \text{ ∧ } \text{SC}_1.\text{S\#} \neq \text{SC}_2.\text{S\#}}(\text{SC}_1 \times \text{SC}_2))

(6) Retrieve the Course IDs (C#) and Course Names (CNAME) of courses that all students have taken.

  1. Find all distinct Student IDs: R1ΠS#(S)R_1 \leftarrow \Pi_{\text{S\#}}(\text{S})
  2. Find all (C#, S#) pairs from enrollment: R2ΠC#, S#(SC)R_2 \leftarrow \Pi_{\text{C\#, S\#}}(\text{SC})
  3. Divide course-student pairs by all students to find C# of courses taken by all students: R3R2÷R1R_3 \leftarrow R_2 \div R_1
  4. Join with Courses to get their names: ΠC#, CNAME(CR3)\Pi_{\text{C\#, CNAME}}(\text{C} \bowtie R_3)

(7) Retrieve the Student IDs (S#) of students who have taken at least one course taught by “Jun Cheng”.

  1. Find the Course IDs of courses taught by ‘Jun Cheng’: R1ΠC#(σTEACHER = ’Jun Cheng’(C))R_1 \leftarrow \Pi_{\text{C\#}}(\sigma_{\text{TEACHER = 'Jun Cheng'}}(\text{C}))
  2. Join SC with R_1 on C# and project S#: ΠS#(SCR1)\Pi_{\text{S\#}}(\text{SC} \bowtie R_1)

(8) Retrieve the Student IDs (S#) of students who have taken Course ‘k1’ and Course ‘k5’.

  1. Find S# of students who took ‘k1’: R1ΠS#(σC# = ’k1’(SC))R_1 \leftarrow \Pi_{\text{S\#}}(\sigma_{\text{C\# = 'k1'}}(\text{SC}))
  2. Find S# of students who took ‘k5’: R2ΠS#(σC# = ’k5’(SC))R_2 \leftarrow \Pi_{\text{S\#}}(\sigma_{\text{C\# = 'k5'}}(\text{SC}))
  3. Take the intersection of these two sets of S#: R1R2R_1 \cap R_2

(9) Retrieve the Student Names (SNAME) of students who have taken all available courses.

  1. Find all distinct Course IDs: R1ΠC#(C)R_1 \leftarrow \Pi_{\text{C\#}}(\text{C})
  2. Find all (S#, C#) pairs from enrollment: R2ΠS#, C#(SC)R_2 \leftarrow \Pi_{\text{S\#, C\#}}(\text{SC})
  3. Divide student-course pairs by all courses to find S# of students who took all of them: R3R2÷R1R_3 \leftarrow R_2 \div R_1
  4. Join with Students to get their names: ΠSNAME(SR3)\Pi_{\text{SNAME}}(\text{S} \bowtie R_3)

(10) Retrieve the Student IDs (S#) of students who have taken at least one of the courses taken by student ‘2’.

  1. Find Course IDs taken by student ‘2’: R1ΠC#(σS# = 2(SC))R_1 \leftarrow \Pi_{\text{C\#}}(\sigma_{\text{S\# = 2}}(\text{SC}))
  2. Join SC with R_1 on C# and project S#: ΠS#(SCR1)\Pi_{\text{S\#}}(\text{SC} \bowtie R_1)

(11) Retrieve the Student IDs (S#) and Names (SNAME) of students who have taken the course named “C Programming Language”.

  1. Find the C# for ‘C Programming Language’: R1ΠC#(σCNAME = ’C Programming Language’(C))R_1 \leftarrow \Pi_{\text{C\#}}(\sigma_{\text{CNAME = 'C Programming Language'}}(\text{C}))
  2. Join SC with R_1 to find enrollments for ‘C Programming Language’: R2SCR1R_2 \leftarrow \text{SC} \bowtie R_1
  3. Join R_2 with S to get student details and project S# and SNAME: ΠS#, SNAME(SR2)\Pi_{\text{S\#, SNAME}}(\text{S} \bowtie R_2)

(12) Retrieve the Student IDs (S#) and Names (SNAME) of students who have not failed any course (assuming a failing grade is GRADE <= 60).

  1. Find the S# of students who have failed at least one course: R1ΠS#(σGRADE <= 60(SC))R_1 \leftarrow \Pi_{\text{S\#}}(\sigma_{\text{GRADE <= 60}}(\text{SC}))
  2. Find all distinct S# from the Students table: R2ΠS#(S)R_2 \leftarrow \Pi_{\text{S\#}}(\text{S})
  3. Subtract students who failed from all students to get those who haven’t failed: R3R2R1R_3 \leftarrow R_2 - R_1
  4. Join with Students to get their names: ΠS#, SNAME(SR3)\Pi_{\text{S\#, SNAME}}(\text{S} \bowtie R_3)

Exercise2

For Database Schema:

(1) Retrieve information for students majoring in “English”, including Student ID (S#), Name (SNAME), Course Name (CNAME), and Score (SCORE).

  1. Select students majoring in ‘English’: R1σMAJOR = ’English’(Students)R_1 \leftarrow \sigma_{\text{MAJOR = 'English'}}(\text{Students})
  2. Join with Learning to get their course scores: R2R1LearningR_2 \leftarrow R_1 \bowtie \text{Learning}
  3. Join with Courses to get course names: R3R2CoursesR_3 \leftarrow R_2 \bowtie \text{Courses}
  4. Project the required attributes: ΠS#, SNAME, CNAME, SCORE(R3)\Pi_{\text{S\#, SNAME, CNAME, SCORE}}(R_3)

(2) Retrieve Student ID (S#), Name (SNAME), Major (MAJOR), and Score (SCORE) for all students whose ‘Database Principles’ course score is greater than 90.

  1. Select the ‘Database Principles’ course: R1σCNAME = ’Database Principles’(Courses)R_1 \leftarrow \sigma_{\text{CNAME = 'Database Principles'}}(\text{Courses})
  2. Join with Learning to find students who took this course and their scores: R2R1LearningR_2 \leftarrow R_1 \bowtie \text{Learning}
  3. Filter for scores greater than 90: R3σSCORE > 90(R2)R_3 \leftarrow \sigma_{\text{SCORE > 90}}(R_2)
  4. Join with Students to get student details: R4R3StudentsR_4 \leftarrow R_3 \bowtie \text{Students}
  5. Project the required attributes: πS#, SNAME, MAJOR, SCORE(R4)\pi_{\text{S\#, SNAME, MAJOR, SCORE}}(R_4)

(3) Retrieve Student ID (S#), Name (SNAME), and Major (MAJOR) for students who did not take course ‘C135’.

  1. Find Student IDs (S#) of students who did take course ‘C135’: R1ΠS#(σC# = ’C135’(Learning))R_1 \leftarrow \Pi_{\text{S\#}}(\sigma_{\text{C\# = 'C135'}}(\text{Learning}))
  2. Find all distinct Student IDs (S#) from the Students table: R2ΠS#(Students)R_2 \leftarrow \Pi_{\text{S\#}}(\text{Students})
  3. Subtract students who took ‘C135’ from all students to find those who didn’t: R3R2R1R_3 \leftarrow R_2 - R_1
  4. Join with Students to get their names and majors: ΠS#, SNAME, MAJOR(StudentsR3)\Pi_{\text{S\#, SNAME, MAJOR}}(\text{Students} \bowtie R_3)

4. Retrieve the information (Student ID (S#), Name (SNAME), and Major (MAJOR)) of all students who did not fail any course (assuming a failing grade is SCORE < 60).

  1. Find the S# of students who have failed at least one course (SCORE < 60): R1ΠS#(σSCORE < 60(Learning))R_1 \leftarrow \Pi_{\text{S\#}}(\sigma_{\text{SCORE < 60}}(\text{Learning}))
  2. Find all distinct S# from the Students table: R2ΠS#(Students)R_2 \leftarrow \Pi_{\text{S\#}}(\text{Students})
  3. Subtract students who failed from all students: R3R2R1R_3 \leftarrow R_2 - R_1
  4. Join with the Students table to get their name and major, then project: ΠS#, SNAME, MAJOR(StudentsR3)\Pi_{\text{S\#, SNAME, MAJOR}}(\text{Students} \bowtie R_3)

Exercise3

For Database Schema:

(1) Retrieve information for students majoring in “International Trade” and receiving a scholarship, including Student ID (S#), Name (SNAME), Course Name (CNAME), and Score (SCORE).

  1. Select students majoring in ‘International Trade’ and receiving a scholarship: R1σMAJOR = ’International Trade’ ∧ SCHOLARSHIP > 0(Students)R_1 \leftarrow \sigma_{\text{MAJOR = 'International Trade' ∧ SCHOLARSHIP > 0}}(\text{Students})
  2. Join with Learning to get their course scores: R2R1LearningR_2 \leftarrow R_1 \bowtie \text{Learning}
  3. Join with Courses to get course names: R3R2CoursesR_3 \leftarrow R_2 \bowtie \text{Courses}
  4. Project the required attributes: ΠS#, SNAME, CNAME, SCORE(R3)\Pi_{\text{S\#, SNAME, CNAME, SCORE}}(R_3)

(2) Retrieve Course ID (C#), Name (CNAME), and Credit (CREDIT) for courses where a student achieved a perfect score (100).

  1. Select entries from Learning where SCORE is 100: R1σSCORE = 100(Learning)R_1 \leftarrow \sigma_{\text{SCORE = 100}}(\text{Learning})
  2. Join with Courses to get course details: R2R1CoursesR_2 \leftarrow R_1 \bowtie \text{Courses}
  3. Project the required attributes (duplicates will be removed by projection): ΠC#, CNAME, CREDIT(R2)\Pi_{\text{C\#, CNAME, CREDIT}}(R_2)

(3) Retrieve Student ID (S#), Name (SNAME), and Major (MAJOR) for students who did not receive a scholarship and have at least one course score above 95.

  1. Find Student IDs (S#) of students who did not receive a scholarship: R1ΠS#(σSCHOLARSHIP = 0(Students))R_1 \leftarrow \Pi_{\text{S\#}}(\sigma_{\text{SCHOLARSHIP = 0}}(\text{Students}))
  2. Find Student IDs (S#) of students with at least one score > 95: R2ΠS#(σSCORE > 95(Learning))R_2 \leftarrow \Pi_{\text{S\#}}(\sigma_{\text{SCORE > 95}}(\text{Learning}))
  3. Find students who satisfy both conditions (intersection): R3R1R2R_3 \leftarrow R_1 \cap R_2
  4. Join with Students to get their names and majors: ΠS#, SNAME, MAJOR(StudentsR3)\Pi_{\text{S\#, SNAME, MAJOR}}(\text{Students} \bowtie R_3)

(4) Retrieve Student ID (S#), Name (SNAME), and Major (MAJOR) for all students who have no course score below 80.

  1. Find Student IDs (S#) of students who do have at least one course score below 80: R1ΠS#(σSCORE < 80(Learning))R_1 \leftarrow \Pi_{\text{S\#}}(\sigma_{\text{SCORE < 80}}(\text{Learning}))
  2. Find all distinct Student IDs (S#) from the Students table: R2ΠS#(Students)R_2 \leftarrow \Pi_{\text{S\#}}(\text{Students})
  3. Subtract students who have scores below 80 from all students: R3R2R1R_3 \leftarrow R_2 - R_1
  4. Join with Students to get their names and majors: ΠS#, SNAME, MAJOR(StudentsR3)\Pi_{\text{S\#, SNAME, MAJOR}}(\text{Students} \bowtie R_3)

Here are the relational algebra expressions for the two problem sets, translated into English.

Exercise4

Database Schema:

(1) Retrieve the Course Numbers (cnum) of courses not taken by student “Xiang Liu”.

  1. Find the snum of “Xiang Liu”: R1Πsnum(σsname = ’Xiang Liu’(S))R_1 \leftarrow \Pi_{\text{snum}}(\sigma_{\text{sname = 'Xiang Liu'}}(\text{S}))
  2. Find the cnum of courses taken by “Xiang Liu”: R2Πcnum(SCR1)R_2 \leftarrow \Pi_{\text{cnum}}(\text{SC} \bowtie R_1)
  3. Find all distinct cnum from the Courses table: R3Πcnum(C)R_3 \leftarrow \Pi_{\text{cnum}}(\text{C})
  4. Subtract courses taken by “Xiang Liu” from all available courses: ResultR3R2\text{Result} \leftarrow R_3 - R_2

(2) Retrieve the names (sname) of male students who have at least one course score above 90.

  1. Find the snum of male students: R1Πsnum(σsex = ’M’(S))R_1 \leftarrow \Pi_{\text{snum}}(\sigma_{\text{sex = 'M'}}(\text{S}))
  2. Find the snum of students who have at least one course score above 90: R2Πsnum(σscore > 90(SC))R_2 \leftarrow \Pi_{\text{snum}}(\sigma_{\text{score > 90}}(\text{SC}))
  3. Intersect these two sets of snum to find male students with scores > 90: R3R1R2R_3 \leftarrow R_1 \cap R_2
  4. Join with Students to get their names and project: ResultΠsname(SR3)\text{Result} \leftarrow \Pi_{\text{sname}}(\text{S} \bowtie R_3)

(3) List the names (sname) of students who did not select the course “Artificial Intelligence”.

  1. Find the cnum for “Artificial Intelligence”: R1Πcnum(σcname = ’Artificial Intelligence’(C))R_1 \leftarrow \Pi_{\text{cnum}}(\sigma_{\text{cname = 'Artificial Intelligence'}}(\text{C}))
  2. Find the snum of students who did select “Artificial Intelligence”: R2Πsnum(SCR1)R_2 \leftarrow \Pi_{\text{snum}}(\text{SC} \bowtie R_1)
  3. Find all distinct snum from the Students table: R3Πsnum(S)R_3 \leftarrow \Pi_{\text{snum}}(\text{S})
  4. Subtract students who took “Artificial Intelligence” from all students: R4R3R2R_4 \leftarrow R_3 - R_2
  5. Join with Students to get their names and project: ResultΠsname(SR4)\text{Result} \leftarrow \Pi_{\text{sname}}(\text{S} \bowtie R_4)

(4) Find the names (sname) of students who have taken all courses taught by “Teacher Yuan”.

  1. Find all cnum taught by “Teacher Yuan”: R1Πcnum(σteacher = ’Teacher Yuan’(C))R_1 \leftarrow \Pi_{\text{cnum}}(\sigma_{\text{teacher = 'Teacher Yuan'}}(\text{C}))
  2. Find all (snum, cnum) pairs from SC: R2Πsnum, cnum(SC)R_2 \leftarrow \Pi_{\text{snum, cnum}}(\text{SC})
  3. Perform division to find snum of students who took all courses from R_1: R3R2÷R1R_3 \leftarrow R_2 \div R_1
  4. Join with Students to get their names and project: ResultΠsname(SR3)\text{Result} \leftarrow \Pi_{\text{sname}}(\text{S} \bowtie R_3)

(5) Find the names (sname) of students for whom every course score is above 70 AND their average score for all courses is above 75.

Exercise5

Database Schema:

(1) Provide the Supplier Numbers (SNO) of suppliers who supply Project J1.

ResultΠSNO(σJNO = ’J1’(SPJ))\text{Result} \leftarrow \Pi_{\text{SNO}}(\sigma_{\text{JNO = 'J1'}}(\text{SPJ}))

(2) Provide all supply details (tuples from SPJ) where the quantity (QTY) is between 300 and 500 (inclusive).

ResultσQTY >= 300 ∧ QTY <= 500(SPJ)\text{Result} \leftarrow \sigma_{\text{QTY >= 300 ∧ QTY <= 500}}(\text{SPJ})

(3) Provide the Part Numbers (PNO) of parts supplied by suppliers in ‘London’ to projects in ‘London’.

  1. Find SNO of suppliers in ‘London’: R1ΠSNO(σCITY = ’London’(S))R_1 \leftarrow \Pi_{\text{SNO}}(\sigma_{\text{CITY = 'London'}}(\text{S}))
  2. Find JNO of projects in ‘London’: R2ΠJNO(σCITY = ’London’(J))R_2 \leftarrow \Pi_{\text{JNO}}(\sigma_{\text{CITY = 'London'}}(\text{J}))
  3. Join SPJ with R_1 and R_2 and project PNO: ResultΠPNO((SPJR1)R2)\text{Result} \leftarrow \Pi_{\text{PNO}}((\text{SPJ} \bowtie R_1) \bowtie R_2)

(4) Provide all Part Numbers (PNO) that satisfy the following condition: the supplier providing the part and the project using the part are in the same city.

  1. Join Suppliers, Supply, and Projects tables: R1SSPJJR_1 \leftarrow \text{S} \bowtie \text{SPJ} \bowtie \text{J}
  2. Select tuples where S.CITY equals J.CITY: R2σS.CITY = J.CITY(R1)R_2 \leftarrow \sigma_{\text{S.CITY = J.CITY}}(R_1)
  3. Project the PNO: ResultΠPNO(R2)\text{Result} \leftarrow \Pi_{\text{PNO}}(R_2)

(5) Provide the Project Names (JNAME) of all projects supplied by supplier S1.

  1. Select supply records for S1: R1σSNO = ’S1’(SPJ)R_1 \leftarrow \sigma_{\text{SNO = 'S1'}}(\text{SPJ})
  2. Join with Projects to get project details: R2R1JR_2 \leftarrow R_1 \bowtie \text{J}
  3. Project JNAME: ResultΠJNAME(R2)\text{Result} \leftarrow \Pi_{\text{JNAME}}(R_2)

(6) Provide the Project Names (JNAME) of projects that use parts supplied by suppliers who supply ‘red’ parts. (Assuming “red parts” means parts with COLOR = 'Red', and “suppliers who supply red parts” means suppliers who supply at least one red part).

  1. Find PNO of red parts: R1ΠPNO(σCOLOR = ’Red’(P))R_1 \leftarrow \Pi_{\text{PNO}}(\sigma_{\text{COLOR = 'Red'}}(\text{P}))
  2. Find SNO of suppliers who supply these red parts: R2ΠSNO(SPJR1)R_2 \leftarrow \Pi_{\text{SNO}}(\text{SPJ} \bowtie R_1)
  3. Find JNO of projects involved with these suppliers: R3ΠJNO(R2SPJ)R_3 \leftarrow \Pi_{\text{JNO}}(R_2 \bowtie \text{SPJ})
  4. Join with Projects to get JNAME: ResultΠJNAME(JR3)\text{Result} \leftarrow \Pi_{\text{JNAME}}(\text{J} \bowtie R_3)

(7) Find the Project Names (JNAME) of projects that use all parts.

  1. Find all distinct PNO from the Parts table: R1ΠPNO(P)R_1 \leftarrow \Pi_{\text{PNO}}(\text{P})
  2. Find all (JNO, PNO) pairs from SPJ: R2ΠJNO, PNO(SPJ)R_2 \leftarrow \Pi_{\text{JNO, PNO}}(\text{SPJ})
  3. Perform division to find JNO of projects using all parts: R3R2÷R1R_3 \leftarrow R_2 \div R_1
  4. Join with Projects to get JNAME: ResultΨJNAME(JR3)\text{Result} \leftarrow \Psi_{\text{JNAME}}(\text{J} \bowtie R_3)

(8) Find the Supplier Names (SNAME) of suppliers who supply both parts P1 and P2.

  1. Find SNO that supply P1: R1ΠSNO(σPNO = ’P1’(SPJ))R_1 \leftarrow \Pi_{\text{SNO}}(\sigma_{\text{PNO = 'P1'}}(\text{SPJ}))
  2. Find SNO that supply P2: R2ΠSNO(σPNO = ’P2’(SPJ))R_2 \leftarrow \Pi_{\text{SNO}}(\sigma_{\text{PNO = 'P2'}}(\text{SPJ}))
  3. Intersect these sets of SNO: R3R1R2R_3 \leftarrow R_1 \cap R_2
  4. Join with Suppliers to get SNAME and project: ResultΠSNAME(SR3)\text{Result} \leftarrow \Pi_{\text{SNAME}}(\text{S} \bowtie R_3)

(9) Display the Part Names (PNAME) of parts that have the same color as the part named “TV”. (Assuming “TV” is a PNAME value).

  1. Find the COLOR of the part named “TV”: R1ΠCOLOR(σPNAME = ’TV’(P))R_1 \leftarrow \Pi_{\text{COLOR}}(\sigma_{\text{PNAME = 'TV'}}(\text{P}))
  2. Find PNAME of parts with that COLOR: R2PR1R_2 \leftarrow \text{P} \bowtie R_1
  3. Project PNAME (excluding the part ‘TV’ itself if required, but the query doesn’t specify exclusion): ResultΠPNAME(R2)\text{Result} \leftarrow \Pi_{\text{PNAME}}(R_2)

(10) Find the Project Names (JNAME) of projects that use all parts supplied by S1.

  1. Find all distinct PNO supplied by S1: R1ΠPNO(σSNO = ’S1’(SPJ))R_1 \leftarrow \Pi_{\text{PNO}}(\sigma_{\text{SNO = 'S1'}}(\text{SPJ}))
  2. Find all (JNO, PNO) pairs from SPJ: R2ΠJNO, PNO(SPJ)R_2 \leftarrow \Pi_{\text{JNO, PNO}}(\text{SPJ})
  3. Perform division to find JNO of projects using all parts from R_1: R3R2÷R1R_3 \leftarrow R_2 \div R_1
  4. Join with Projects to get JNAME: ResultΠJNAME(JR3)\text{Result} \leftarrow \Pi_{\text{JNAME}}(\text{J} \bowtie R_3)

Exercise6

Database Schema:

(1) Find the names (Sname) and ages (Sage) of all students in the ‘CS’ department.

ResultΠSname, Sage(σSdept = ’CS’(Student))\text{Result} \leftarrow \Pi_{\text{Sname, Sage}}(\sigma_{\text{Sdept = 'CS'}}(\text{Student}))

(2) Find the student IDs (Sno) of all students who have a grade less than 60.

ResultΠSno(σGrade < 60(SC))\text{Result} \leftarrow \Pi_{\text{Sno}}(\sigma_{\text{Grade < 60}}(\text{SC}))

(3) Find the names (Sname) and departments (Sdept) of students who took course ‘C002’.

  1. Find Sno of students who took ‘C002’: R1ΠSno(σCno = ’C002’(SC))R_1 \leftarrow \Pi_{\text{Sno}}(\sigma_{\text{Cno = 'C002'}}(\text{SC}))
  2. Join with Student to get their names and departments: ResultΠSname, Sdept(StudentR1)\text{Result} \leftarrow \Pi_{\text{Sname, Sdept}}(\text{Student} \bowtie R_1)

(4) Find the student IDs (Sno) of those who took both course ‘C001’ and ‘C002’.

  1. Find Sno of students who took ‘C001’: R1ΠSno(σCno = ’C001’(SC))R_1 \leftarrow \Pi_{\text{Sno}}(\sigma_{\text{Cno = 'C001'}}(\text{SC}))
  2. Find Sno of students who took ‘C002’: R2ΠSno(σCno = ’C002’(SC))R_2 \leftarrow \Pi_{\text{Sno}}(\sigma_{\text{Cno = 'C002'}}(\text{SC}))
  3. Intersect the two sets of Sno: ResultR1R2\text{Result} \leftarrow R_1 \cap R_2

(5) Find the names (Sname) of students who took ‘C001’ but not ‘C002’.

  1. Find Sno of students who took ‘C001’: R1ΠSno(σCno = ’C001’(SC))R_1 \leftarrow \Pi_{\text{Sno}}(\sigma_{\text{Cno = 'C001'}}(\text{SC}))
  2. Find Sno of students who took ‘C002’: R2ΠSno(σCno = ’C002’(SC))R_2 \leftarrow \Pi_{\text{Sno}}(\sigma_{\text{Cno = 'C002'}}(\text{SC}))
  3. Find Sno of students who took ‘C001’ but not ‘C002’: R3R1R2R_3 \leftarrow R_1 - R_2
  4. Join with Student to get their names: ResultΠSname(StudentR3)\text{Result} \leftarrow \Pi_{\text{Sname}}(\text{Student} \bowtie R_3)

(6) Find students (Sno) who took all the courses taken by student ‘S001’.

  1. Find all Cno taken by student ‘S001’: R1ΠCno(σSno = ’S001’(SC))R_1 \leftarrow \Pi_{\text{Cno}}(\sigma_{\text{Sno = 'S001'}}(\text{SC}))
  2. Use the SC table (projected to Sno, Cno) and R_1 in a division operation: ResultΠSno, Cno(SC)÷R1\text{Result} \leftarrow \Pi_{\text{Sno, Cno}}(\text{SC}) \div R_1

(7) Find the name (Cname) of the prerequisite course for ‘Data Structures’.

  1. Find the Cno of ‘Data Structures’: R1σCname = ’Data Structures’(Course)R_1 \leftarrow \sigma_{\text{Cname = 'Data Structures'}}(\text{Course})

  2. Join R_1 with Course (aliased to find the prerequisite):

    R2ρCourseDS(CnoDS, CnameDS, CpnoDS)(R1)R_2 \leftarrow \rho_{\text{CourseDS(\text{CnoDS}, \text{CnameDS}, \text{CpnoDS})}}(R_1)

    R3σCourse.Cno = R2.CpnoDS(Course×R2)R_3 \leftarrow \sigma_{\text{Course.Cno = R2.CpnoDS}}(\text{Course} \times R_2)

  3. Project the Cname of the prerequisite course: ResultΠCname(R3)\text{Result} \leftarrow \Pi_{\text{Cname}}(R_3)

(8) For each course, find the number of students enrolled and the average grade.

ResultGCno;COUNT(Sno) AS NumStudents, AVG(Grade) AS AverageGrade(SC)\text{Result} \leftarrow \mathcal{G}_{\text{Cno}; \text{COUNT(Sno) AS NumStudents, AVG(Grade) AS AverageGrade}}(\text{SC})

(9) Find the student IDs (Sno) and average grades (AverageGrade) of students whose average grade is greater than 85.

  1. Calculate the average grade for each student: R1GSno;AVG(Grade) AS AverageGrade(SC)R_1 \leftarrow \mathcal{G}_{\text{Sno}; \text{AVG(Grade) AS AverageGrade}}(\text{SC})
  2. Select students whose AverageGrade is greater than 85: ResultσAverageGrade > 85(R1)\text{Result} \leftarrow \sigma_{\text{AverageGrade > 85}}(R_1)

(10) Find the names (Sname) of students enrolled in more than 3 courses.

  1. Count the number of courses each student is enrolled in: R1GSno;COUNT(Cno) AS NumCourses(SC)R_1 \leftarrow \mathcal{G}_{\text{Sno}; \text{COUNT(Cno) AS NumCourses}}(\text{SC})
  2. Select students enrolled in more than 3 courses: R2ΠSno(σNumCourses > 3(R1))R_2 \leftarrow \Pi_{\text{Sno}}(\sigma_{\text{NumCourses > 3}}(R_1))
  3. Join with Student to get their names: ResultΠSname(StudentR2)\text{Result} \leftarrow \Pi_{\text{Sname}}(\text{Student} \bowtie R_2)

Next Post
rCore (RISC-V) 学习笔记