Back to the map

Module 17 · SQL and relational algebra · Lesson 1 of 5

Relational algebra

The small set of operators every SQL query compiles to: selection, projection, rename, union, difference, Cartesian product, joins and division. How to write and read algebra expressions, and why the optimizer rewrites them.

CoreMust-knowMid 13 min Updated Nov 2026

Why it matters

SQL is what you write; relational algebra is what the database actually executes. The optimizer turns every query into a tree of algebra operators, rearranges the tree into a cheaper equivalent, and runs it. Exams ask you to write algebra for English questions, and understanding the operators explains why a query plan looks the way it does and why some SQL rewrites make no difference while others matter enormously.

The idea

Relational algebra is a set of operators that each take one or two relations and produce a new relation. Because the output is always a relation, operators compose into expressions, just as arithmetic operators compose numbers. Six operators are fundamental; the rest can be built from them.

OperatorSymbolDoesSQL equivalent
Selectionσ condition (R)Keeps the tuples satisfying a conditionWHERE
Projectionπ attributes (R)Keeps chosen attributes, removes duplicatesSELECT DISTINCT columns
Renameρ name (R)Renames a relation or its attributesAS
UnionR ∪ STuples in either (same schema required)UNION
Set differenceR − STuples in R but not in SEXCEPT
Cartesian productR × SEvery pairing of a tuple of R with a tuple of SFROM R, S (CROSS JOIN)
The six fundamental operators. Union and difference need union-compatible relations: same number of attributes with matching domains.

Derived operators

OperatorDefined asSQL equivalent
Intersection R ∩ SR − (R − S)INTERSECT
Theta join R ⋈θ Sσθ (R × S)JOIN ... ON condition
Equi-joinTheta join whose condition uses only =JOIN ... ON a = b
Natural join R ⋈ SEqui-join on all same-named attributes, keeping one copy of eachNATURAL JOIN or JOIN ... USING
Left / right / full outer joinJoin plus unmatched tuples padded with NULLLEFT / RIGHT / FULL JOIN
Semi-join R ⋉ STuples of R that have a match in SWHERE EXISTS (...)
Division R ÷ STuples of R related to every tuple of SDouble NOT EXISTS
Assignmenttemp ← expressionWITH (a CTE)

Writing expressions

Work from the inside out. "Names of employees in the Research department": join Employee with Department on dept_id, select Research, project names:

π name (σ dname = 'Research' (Employee ⋈ Department))

The same query can be written with the selection pushed inside the join, which produces the same result much more cheaply because the join sees one department instead of all:

π name (Employee ⋈ σ dname = 'Research' (Department))

as writtenπ nameσ Research⋈EmployeeDepartmentselection pushed downπ name⋈Employeeσ ResearchDepartment
Two equivalent query trees. Pushing the selection below the join shrinks the join's input, the most important rewrite an optimizer makes.

Division: the "for all" operator

Division answers questions with "every" or "all": students who have taken every subject in a list, suppliers who supply all red parts. If Takes(student, subject) and Required(subject), then Takes ÷ Required gives the students related to every required subject. It is defined as π student (Takes) − π student ((π student (Takes) × Required) − Takes): all students, minus those missing at least one required subject. In SQL it becomes a double NOT EXISTS ("there is no required subject that this student has not taken") or a GROUP BY with HAVING COUNT equal to the number of required subjects.

Algebra versus calculus

Relational algebra is procedural: an expression describes the steps. Relational calculus (tuple and domain calculus) is declarative: it describes the result as a logical formula ("tuples t such that..."). Codd showed they have the same expressive power for safe queries, and a language with that power is called relationally complete. SQL is based on calculus-style declarations and compiled into algebra, with extensions (aggregation, ordering, duplicates, NULLs) that pure algebra lacks.

Trade-offs

Pure relational algebra works on sets, has no aggregation or ordering, and ignores NULLs, which keeps it clean enough to prove equivalences that optimizers rely on. Real engines extend it to bags (duplicates), grouping and outer joins, and those extensions restrict which rewrites are valid. Knowing which algebraic laws hold (selection pushdown, join commutativity and associativity) explains what the optimizer is allowed to change.

In an interview

Translate a question into algebra out loud and then optimise it: "Project names from the join of Employee and Department filtered to Research. I would push the selection onto Department first so the join only sees matching departments; projection can also be pushed down to carry fewer columns." For "find X related to all Y", name division and give the double NOT EXISTS form.

Check yourself

Which operation answers 'find students who have taken every subject offered by the Mathematics department'?

Relational algebra · Backplane