Relational algebra: basic operators
Writing queries with selection, projection, set operations, the Cartesian product and rename; the basis of the “write the relational algebra expression” and “give the result” exam questions.
Relational algebra is a small set of operators that work on relations (tables) and whose result is again a relation. This is the mathematics behind SQL. The database engine first translates your SQL query into an expression like this, then optimizes it. The exam has two kinds of questions: “Write a relational algebra expression for …” and “Give the result of this expression”. For both, knowing the six fundamental operators on this page is enough.
Golden rules:
- σ selects rows, π selects columns. Whoever mixes them up loses the easiest points.
- Every result is a set. There are no repeated rows; π removes duplicates.
- ∪, −, ∩ are only done between union-compatible relations.
- × alone is almost never useful. A σ with the matching condition follows it.
- Read the expression from the inside out. The innermost parentheses are evaluated first.
The sample database
We use the same small university database all semester. These are the tables needed most on this page.
student
| stu_id | name | dept_name | tot_cred |
|---|---|---|---|
| S1 | Ada | CS | 60 |
| S2 | Bora | CS | 30 |
| S3 | Cem | EE | 45 |
| S4 | Defne | MATH | 90 |
| S5 | Ece | CS | 15 |
| S6 | Firat | EE | 0 |
| S7 | Gizem | NULL | 10 |
course
| course_id | title | dept_name | credits |
|---|---|---|---|
| CS101 | Intro to Programming | CS | 4 |
| CS201 | Data Structures | CS | 4 |
| CS305 | Databases | CS | 3 |
| EE210 | Circuits | EE | 3 |
| MA101 | Calculus | MATH | 4 |
| MA202 | Linear Algebra | MATH | 3 |
| BI100 | Biology | BIO | 3 |
takes (S6 has taken no course, S3 has no grade yet for CS101)
| stu_id | course_id | grade |
|---|---|---|
| S1 | CS101 | A |
| S1 | CS201 | B |
| S1 | CS305 | A |
| S1 | MA101 | B |
| S2 | CS101 | B |
| S2 | CS201 | C |
| S3 | EE210 | A |
| S3 | MA101 | C |
| S3 | CS101 | NULL |
| S4 | MA101 | A |
| S4 | MA202 | A |
| S4 | CS305 | B |
| S5 | CS101 | F |
| S7 | MA202 | B |
instructor and department
| inst_id | name | dept_name | salary |
|---|---|---|---|
| I1 | Aksoy | CS | 95000 |
| I2 | Demir | CS | 80000 |
| I3 | Kaya | EE | 85000 |
| I4 | Sahin | MATH | 70000 |
| I5 | Celik | MATH | 72000 |
| I6 | Yildiz | BIO | 60000 |
| dept_name | building | budget |
|---|---|---|
| CS | Galata | 500000 |
| EE | Galata | 350000 |
| MATH | Rumeli | 200000 |
| BIO | Kadikoy | 150000 |
teaches(inst_id, course_id): (I1, CS101), (I1, CS305), (I2, CS201), (I3, EE210), (I4, MA101), (I5, MA202). I6 teaches no course, and nobody teaches BI100.
Selection: σ
Selection returns the rows of that satisfy the condition . The columns stay as they are. The condition uses comparison operators () and logical connectives ( and, or, not).
| stu_id | name | dept_name | tot_cred |
|---|---|---|---|
| S1 | Ada | CS | 60 |
| S2 | Bora | CS | 30 |
| S5 | Ece | CS | 15 |
If two conditions concern the same row, they combine in a single selection: gives S1 (Ada) and S2 (Bora).
The order of selections does not matter: .
Projection: π
Projection keeps only the listed columns. Because a relation is a set, duplicate rows are removed.
| dept_name |
|---|
| CS |
| EE |
| MATH |
| NULL |
There are 7 students but the result has 4 rows. In SQL, SELECT dept_name FROM student returns 7 rows; to get the same result as relational algebra you need to write SELECT DISTINCT. SQL uses multiset semantics, algebra uses set semantics.
PITFALL · π can reduce the number of rows. For a “How many tuples?” question, do not just count the table and move on. After a projection, count rows that look the same as one.
Composition
Since the result of every operator is a relation, operators can be nested. The names of instructors who earn more than 75000:
The order matters: first σ, then π. If you write the opposite (), the expression is invalid, because after the projection the salary column no longer exists.
Set operations: ∪, −, ∩
All three require the two relations to be union-compatible:
- the same degree (arity), that is, the same number of columns,
- the domains of the th columns are the same.
Column names do not have to be the same; the result takes the names of the left relation.
Let us work with the courses taken by S1 and S4: = {CS101, CS201, CS305, MA101}, = {MA101, MA202, CS305}.
| Expression | Meaning | Result |
|---|---|---|
| taken by at least one of them | CS101, CS201, CS305, MA101, MA202 | |
| taken by both | CS305, MA101 | |
| taken by S1 but not by S4 | CS101, CS201 | |
| taken by S4 but not by S1 | MA202 |
Difference is not commutative: . Intersection is not counted as a fundamental operator, because it can be written with difference: .
“None” questions with difference. Courses that no student has taken:
Departments that have both students and instructors are an intersection: = {CS, EE, MATH}. BIO has no students, and NULL has no instructors.
Cartesian product: ×
puts each row of next to each row of . The number of rows is , the number of columns is the sum of the degrees. Columns with the same name are told apart by the table name.
: rows, columns (instructor.dept_name and department.dept_name are separate).
Most of these 24 rows are meaningless: it pairs Aksoy with the BIO building. You keep the meaningful ones with a selection:
| name | building |
|---|---|
| Aksoy | Galata |
| Demir | Galata |
| Kaya | Galata |
| Sahin | Rumeli |
| Celik | Rumeli |
| Yildiz | Kadikoy |
Of the 24 rows, 6 remained, each instructor with their own department. This “multiply, then select by equality” pattern is the definition of a join. Next week we will abbreviate it with ⋈.
PITFALL · forgetting the matching condition. If you do not write a σ after the product, fake rows like “every instructor in every building” get into the result. In every expression with a product, ask “which column links the tables?”
Rename: ρ
gives the result of expression the name . also renames the columns. Its real job: comparing a table with itself. Without giving the two copies different names, you cannot say which salary in comes from which copy.
Example: the highest salary (without aggregate functions). The idea: the highest salary is a salary for which no higher salary exists.
1) ρ_i(instructor) × ρ_j(instructor) 36 rows
2) σ_{i.salary < j.salary}(...) there is a j that earns more than i
3) π_{i.salary}(...) = {80000, 85000, 70000, 72000, 60000}
4) π_salary(instructor) − (3) = {95000}
If you change the condition to , the same pattern gives the lowest salary (60000).
Fundamental and derived operators
There are six fundamental operators: . Every relational algebra query can be written with them. , joins and division are derived from these six; they are only shorthand.
| Operator | Kind | Input | Degree of result |
|---|---|---|---|
| unary | 1 relation | degree(R) | |
| unary | 1 relation | ||
| unary | 1 relation | degree(R) | |
| , | binary | 2 compatible relations | degree(R) |
| binary | 2 relations | degree(R) + degree(S) |
Query tree
An expression is drawn as a tree: leaves are tables, inner nodes are operators, the root is the result. For the instructor building query:
π name, building
|
σ instructor.dept_name = department.dept_name
|
×
/ \
instructor department
The tree is evaluated from bottom to top. In the optimization week (week 13) we will compare different trees of the same query and see why pushing σ below the product is cheap.
Method for solving questions
For a “Write the relational algebra” question, follow this order:
- Which tables are needed? If more than one, take the product and equate the linking columns.
- Put the row conditions in σ.
- Take the requested columns with π on the outside.
- If the question has “both / every / never / only”, you need a set operation: “both” → ∩, “never” → difference.
Example: the names of students who take courses outside their own department. Three tables are needed, two matching conditions and one inequality condition:
The product has rows, and after the selection Ada, Cem and Defne remain. Because Gizem’s department is NULL, the comparison does not come out true and the row is dropped.
Common mistakes
| Wrong idea | The truth |
|---|---|
| π preserves the number of rows | It removes duplicates; has 3 rows |
| For “took both”, | A single row cannot take two values, so it returns empty. Build two sets, take ∩ |
| First π, then σ on that column | π does not bring back the column it dropped; write σ first |
| If both relations have the same number of columns, ∪ works | The domains must also match in order |
| Difference is not commutative | |
| The number of rows of is | They are multiplied: |
| ρ is not needed for a self-product | The names clash; separate the two copies with ρ |
| NULL ≠ ‘CS’ is true | Every comparison with NULL is unknown, and the row is not selected |
Test yourself
Exam-style questions. Solve them on paper first, then reveal the answer.
Give the result of on the sample database.
Show answer
First the selection: the rows of the course table with credits = 4 are CS101, CS201 and MA101. Then the projection keeps only the course_id column. There are no repeats, so three rows remain.
How many tuples and how many attributes does have?
Show answer
In a Cartesian product the row counts are multiplied and the column counts are added. student has 7 rows and 4 columns, course has 7 rows and 4 columns. rows, columns. Because both tables have dept_name, the result has two separate columns, student.dept_name and course.dept_name.
Give the result of . How many tuples does it have?
Show answer
department has 4 rows, but CS and EE are both in Galata. Relational algebra uses set semantics, and projection removes duplicates. The result has 3 rows, not 4: Galata, Rumeli, Kadikoy.
Write a relational algebra expression that returns the names of instructors in the MATH department whose salary is greater than 71000. Give the result.
Show answer
Since both conditions concern the same row, they are combined with in a single selection:.
The MATH instructors are Sahin (70000) and Celik (72000). Only Celik is above 71000.
Give the result of . What does it mean in plain English?
Show answer
The left set is all courses (7 courses). The right set is the courses that appear in teaches: CS101, CS305, CS201, EE210, MA101, MA202. The difference is what is on the left but not on the right: BI100. Meaning: courses that no instructor teaches.
Write a relational algebra expression for the IDs of students who took both CS101 and MA101. Give the result.
Show answer
Questions that ask for “both” cannot be solved with a single selection: returns empty, because the course_id value of one row cannot be two things at once. The right way is to build two separate sets and take the intersection.
Students who took CS101: S1, S2, S3, S5. Students who took MA101: S1, S3, S4. Intersection: S1, S3.
Give the result of .
Show answer
Students who took CS101: S1, S2, S3, S5. Students who took MA202: S4, S7. The union collects both without repeats: S1, S2, S3, S4, S5, S7. The same query can also be written with a single selection: .
Is a valid relational algebra expression? Why?
Show answer
For union, difference and intersection, the two relations must be union-compatible: the same number of columns and, in order, the same kind of domain. The left side has 2 columns and the right side has 1. The expression is invalid. SQLite gives the same error: “do not have the same number of result columns”.
Write a relational algebra expression that returns the IDs of students who have not taken any course. Give the result.
Show answer
The “never did ...” pattern is solved with difference: everyone minus those who did. = S1..S7. = S1, S2, S3, S4, S5, S7. Difference: S6 (Firat).
Using only , , , and (no aggregation), write an expression for the lowest instructor salary. Give the result.
Show answer
To multiply a table by itself, give the two copies different names: (36 rows). keeps the rows where “someone earns less than this one”. Their values cannot be the lowest.
Subtract these from all salaries: 60000 (Yildiz) remains.
Using , , and , write an expression for the names of students who took at least one course offered by a department other than their own. Give the result on the sample data.
Show answer
Multiply the three tables and put the matching conditions and the different-department condition in the selection:.
Ada (CS) took MA101, Cem (EE) took MA101 and CS101, Defne (MATH) took CS305. Gizem's department is NULL: a comparison with NULL does not count as true, so Gizem is not in the result.
How many tuples does return? Is equal to ?
Show answer
The A grades: S1-CS101, S1-CS305, S3-EE210, S4-MA101, S4-MA202. A total of 5 rows.
Two selections in a row are always equal to a single selection, and their order can be swapped (commutative). Both return the two A rows of S4.
Verification: All result tables were computed in verify/SEN2104/04.mjs with JS set operations (lib.mjs: sigma, pi, union, minus, intersect, product, rho), and the SQL equivalent of every expression was run on node:sqlite (SQLite 3.53) and checked to give the same result (54 checks, 0 errors).