G27
Self-checkedTier 1 8 min readdbms.relational-algebra-advanced

Joins, division and expression trees

Joins in depth (theta, equi, natural, left/right/full outer joins and semijoin) with their treatment of NULL, the division operator and its expression with the basic operators, grouping and aggregation, query evaluation as an expression tree, and the heuristic optimisation rules (push selections and projections down, combine a selection with a product into a join, order joins) with measured intermediate sizes.

Why it exists

The six basic operators are enough in theory but awkward in practice: a join is a selection over a product, "for all" needs a complicated expression, and a query written naively can be thousands of times slower than an equivalent one. This page adds the operators actually used and explains how an expression is evaluated and rewritten.

Prerequisites

You need the basic operators and their laws (relational algebra).

Precise definitions

  • Theta join R⋈θS=σθ(R×S)R \bowtie_\theta S = \sigma_\theta(R \times S); an equijoin is a theta join whose condition is a conjunction of equalities; the natural join is the equijoin on all common attributes with one copy of each kept.
  • Left outer join R ⟕ S: the natural join together with the tuples of RR that have no match, padded with NULL for the attributes of SS. Right outer join R ⟖ S: the same for SS. Full outer join R ⟗ S: both.
  • Semijoin R⋉S=πR(R⋈S)R \ltimes S = \pi_{R}(R \bowtie S): the tuples of RR that have a match in SS (only the attributes of RR).
  • Division. Let R(X∪Y)R(X \cup Y) and S(Y)S(Y). Then R÷S={t over X:for every s∈S, (t,s)∈R}R \div S = \{ t \text{ over } X : \text{for every } s \in S, \ (t, s) \in R \}. It answers "for all" queries.
  • Grouping and aggregation Gγf1(A1),…(R)_{G}\gamma_{f_1(A_1), \ldots}(R): group the tuples by the attributes in GG and compute aggregates (COUNT, SUM, AVG, MIN, MAX) per group.

How it works

Outer joins

Outer joins: start

Computed, not typed
Emp, Dept
Emp3 tuples
eidenamedid
1Ravi10
2Sana20
3TaraNULL
Dept3 tuples
diddname
10Sales
20HR
30IT

Step 0

Tara has no department (NULL) and the department IT (30) has no employee.

0 / 4
computed by script: relational operators are evaluated by scripts/db_lib.py (and cross-checked against SQLite), one step at a time. python3 scripts/gen-db1-traces.py

The inner join loses Tara (no department: her did is NULL, and NULL never matches) and the department IT (no employee). The outer joins bring back the unmatched side with NULLs. All three results were also computed by a real database engine (LEFT JOIN, RIGHT JOIN, FULL JOIN) and are identical. Relations of sizes rr and ss: inner ≤\le left, right ≤\le full, and each outer join is at least max⁡\max of the corresponding operand size when that operand is preserved.

Division

"Students enrolled in all the courses of Req" cannot be done with a join alone. Division is defined by an expression of the basic operators:

R÷S=πX(R)−πX((πX(R)×S)−R).R \div S = \pi_X(R) - \pi_X\bigl((\pi_X(R) \times S) - R\bigr).

Read it as: take every candidate xx (first term); build all pairs of a candidate with a required value; subtract the pairs that really exist in RR to get the missing pairs; project to the candidates that miss something; subtract them from the candidates.

Division: start

Computed, not typed
Enrolled(sid, cid) ÷ Req(cid)
Enrolled5 tuples
sidcid
1C1
1C2
2C1
3C2
3C3
Req2 tuples
cid
C1
C2

Step 0

Which students are enrolled in ALL the courses of Req? Division answers 'for all' questions.

0 / 5
computed by script: relational operators are evaluated by scripts/db_lib.py (and cross-checked against SQLite), one step at a time. python3 scripts/gen-db1-traces.py

Only student 1 has both C1 and C2. The identity was checked on 300 random instances and against the double-NOT-EXISTS query a real engine runs. Properties: (R÷S)×S⊆R(R \div S) \times S \subseteq R; if SS is empty the result is every candidate (πX(R)\pi_X(R)); the result has at most ∣πX(R)∣|\pi_X(R)| tuples.

Typical shapes. "Employees who work on all projects": πeid,pid(Works)÷πpid(Project)\pi_{\text{eid}, \text{pid}}(\text{Works}) \div \pi_{\text{pid}}(\text{Project}). "Students who passed all courses taught by X": divide by the (projected) set of those courses. If the divisor is chosen by a condition, apply the selection to the divisor first.

Grouping and aggregates

deptγCOUNT(sid)(Student)_{\text{dept}}\gamma_{\text{COUNT}(\text{sid})}(\text{Student}) gives one tuple per department with the number of students. Aggregates ignore NULLs (except COUNT(*)). Grouping is where the algebra goes beyond the basic operators: it cannot be expressed with σ,π,∪,−,×\sigma, \pi, \cup, -, \times. SQL's GROUP BY and HAVING are its direct counterparts (joins and aggregates).

Expression trees and equivalence rules

A query is evaluated as a tree whose leaves are relations and whose inner nodes are operators; each node produces an intermediate relation consumed by its parent. Two expressions are equivalent if they give the same result on every instance. Rules used by the optimiser:

  1. Selections cascade and commute: σp∧q(R)=σp(σq(R))\sigma_{p \wedge q}(R) = \sigma_p(\sigma_q(R)).
  2. A selection followed by a product is a join: σθ(R×S)=R⋈θS\sigma_\theta(R \times S) = R \bowtie_\theta S.
  3. A selection that mentions attributes of one operand only can be pushed into it: σp(R⋈S)=σp(R)⋈S\sigma_p(R \bowtie S) = \sigma_p(R) \bowtie S.
  4. Joins are commutative and associative, so the order can be chosen.
  5. Projection can be pushed down if the attributes needed above (including join attributes) are kept.
  6. Selection distributes over union and difference: σp(R∪S)=σp(R)∪σp(S)\sigma_p(R \cup S) = \sigma_p(R) \cup \sigma_p(S), σp(R−S)=σp(R)−σp(S)\sigma_p(R - S) = \sigma_p(R) - \sigma_p(S). Projection distributes over union but not over difference or intersection.

Heuristic optimisation

Rules of thumb: (1) break conjunctive selections apart; (2) push selections as far toward the leaves as possible; (3) replace selection-over-product by joins; (4) do the most selective (smallest-result) joins first; (5) push projections down, keeping what is needed later. The goal is to keep the intermediate relations small. The query "attributes of the CS students' enrolments" can be written three ways, all with the same 4 result tuples:

Three equivalent expressions, three different amounts of work: start

Computed by a script, not typed
planintermediate results (tuples)tuples produced in totalfinal result
Plan 1: σ dept='CS' ∧ sid=esid (Student × Enrolled)
Plan 2: push the selection down: σ dept='CS' (Student) ⋈ Enrolled
Plan 3: join first: σ dept='CS' (Student ⋈ Enrolled)

Step 0

Student has 4 tuples and Enrolled 5. Pushing the selection towards the leaves and joining instead of taking a product keeps the intermediate relations small. The sizes are counted by running the expressions.

0 / 3
computed by script: relational operators are evaluated by scripts/db_lib.py (and cross-checked against SQLite), one step at a time. python3 scripts/gen-db1-traces.py

Plan 1 builds the whole product (20 tuples) before selecting. Plan 2 pushes the selection into Student first (2 tuples), then joins (4). Plan 3 joins first (5 tuples) and selects after (4). Work (sum of the intermediate sizes, a crude cost measure): 24, 6 and 9. On realistic tables the differences are huge, which is why the order matters even though the results are equal.

Worked examples

EX 1Which join keeps what

Easy

Emp(1 Ravi 10, 2 Sana 20, 3 Tara NULL) and Dept(10 Sales, 20 HR, 30 IT): inner join 22 tuples; left outer 33 (Tara added); right outer 33 (IT added); full outer 44.

EX 2A division query

Easy

Enrolled(sid, cid) ÷\div Req(cid) with Req = {C1, C2}: students who have both. For Enrolled = {(1, C1), (1, C2), (2, C1), (3, C2), (3, C3)}: only student 1.

EX 3Division with a condition on the divisor

Medium

Students who took every 3-credit course: divisor =πcid(σcredits=3(Course))={C2,C3,C4}= \pi_{\text{cid}}(\sigma_{\text{credits}=3}(\text{Course})) = \{C2, C3, C4\}. Nobody is enrolled in C4 in the sample instance, so the result is empty. If C4 is dropped from Course, the result is the students with both C2 and C3: student 3.

EX 4Choose a better plan

Medium

Query: πsname(σdept=CS∧Student.sid=Enrolled.sid(Student×Enrolled))\pi_{\text{sname}}(\sigma_{\text{dept}=\text{CS} \wedge \text{Student.sid}=\text{Enrolled.sid}}(\text{Student} \times \text{Enrolled})). As written, the product has 4⋅5=204 \cdot 5 = 20 tuples. Rewriting the selection and product as a join and pushing the selection on Student before the join gives 22 and then 44 intermediate tuples, a fraction of the work, for the same answer.

EX 5Typical questions

GATE level

(a) "Division is used for:" queries with 'for all'. (b) "Which of the following is NOT equivalent:" πA(R−S)≡πA(R)−πA(S)\pi_A(R - S) \equiv \pi_A(R) - \pi_A(S) is not equivalent. (c) "Number of tuples in R÷SR \div S at most:" the number of distinct XX-values of RR. (d) "The left outer join of RR and SS has at least how many tuples?" ∣R∣|R|. (e) "Pushing a selection below a join is valid when:" the condition refers only to attributes of one operand. (f) "Full outer join contains:" the inner join plus the dangling tuples of both sides.

Cheat box

Cheat box

  • Outer joins keep unmatched tuples with NULL padding: left keeps RR, right keeps SS, full keeps both. Inner join ⊆\subseteq left, right ⊆\subseteq full.
  • Semijoin: tuples of RR with a match. Division: 'for all'.
  • R÷S=πX(R)−πX((πX(R)×S)−R)R \div S = \pi_X(R) - \pi_X((\pi_X(R) \times S) - R).
  • Push selections down, replace σ over × by ⋈, join the small results first; projection pushes through ∪ only.
  • Aggregation (γ) is beyond the six basic operators.

Traps and GATE patterns

Connections

SQL's JOIN, LEFT JOIN, GROUP BY and NOT EXISTS correspond to these operators (joins and aggregates); the same queries can be written in calculus (tuple relational calculus); the base operators are on the previous page.

PYQs

9 previous year questions from your book. I re-solved each one myself (7 by running or simulating, 2 by reasoning only); the book's key is shown next to my answer. All PYQs

GATE 2022 · MSQ · 1 markQ4 · page 388 of the book
Consider the following three relations in a relational
database:
Employee(eId, eName)
 Brand(bId, bName)
 Own(eId, bId)
Which of the following relational algebra expressions
returns the set of eIds who own all the brands?
  • (a)π eId ( (π eId,bld (Own)) / π bId (Brand) )
  • (b)π eId (Own) - π eId ( (π eId (Own) × π bId (Brand)) - π eId,bld Own ))
  • (c)π eId( π eId,bld (Own) / π bId (Own)
  • (d)π eId ( (π eId (Own) × π bId (Own)) / π bId (Brand) ) DATABASE MANAGEMENT SYSTEM
GATE 2018 · MCQ · 2 marksQ9 · page 389 of the book
Consider the relations r(A, B) and s(B, C), where s,B is a
primary key and r.B is a foreign key referencing s.B.
Consider the query:

DATABASE MANAGEMENT  SYSTEM

Q: r ⟕ (σ B<5 (s))

Let LOJ denote the natural left outer-join operation.
Assume that r and s contain no null values.

Which one of the following queries is NOT equivalent
to Q?
  • (a)σ B<5 (r ⋈ s)
  • (b)σ B<5 (r LOJ s)
  • (c)r LOJ (σ B<5 (s))
  • (d)σ B<5 (r LOJ s)
GATE 2017 · Set 1 · NAT · 2 marksQ11 · page 390 of the book
Consider a database that has the relation schema
 CR(StudentName, CourseName). An instance of the
schema CR is as given below:
CR Table

Student Name
Course Name
SA
CA
SA
CB
SA
CC
SB
CB
SB
CC
SC
CA
SC
CB
SC
CC
SD
CA
SD
CB
SD
CC
SD
CD
SE
CD
SE
CA
SE
CB
SF
CA
SF
CB
SF
CC

The following query is run on the database:
T1 ← π CourseName (σ StudentName = 'SA' (CR))
T2 ← CR ÷ T1
The number of rows in T2 is ______.
GATE 2015 · Set 2 · MCQ · 2 marksQ12 · page 390 of the book
Consider two relations R1(A, B) with the tuples (1, 5), (3,
7) and R2(A, C) = (1, 7), (4, 9).

Assume that R(A, B, C) is the full natural outer join of R1
and R2. Consider the following tuples of the form (A, B,
C): a = (1,5, null), b = (1, null, 7), c = (3, null, 9), d = (4, 7,
null), e = (1, 5, 7), f = (3, 7, null), g = (4, null, 9). Which
one of the following statements is correct?
  • (a)R contains a,b,e,f,g but not c, d.
  • (b)R contains all of a,b,c,d,e,f,g
  • (c)R contains e,f,g but not a,b
  • (d)R contains e but not f,g DATABASE MANAGEMENT SYSTEM
GATE 2014 · Set 3 · NAT · 2 marksQ13 · page 391 of the book
Consider the relational schema given below, where eld
of the relation dependent is a foreign key referring to
empld of the relation employee. Assume that every
employee has at least one associated dependent in the
dependent relation.

employee(empld,empName,empAge)

dependent(depld, eld,depName, depAge).

Consider the following relational algebra query:

ΠempId ( employee ) -ΠempId ( employee
⋈(empId=eID )∧( empAge ≤ depAge ) dependent )

The above query evaluates to the set of emplds of
employees whose age is greater than that of
  • (a)Some dependent
  • (b)All dependents.
  • (c)Some of his/her dependents
  • (d)All of his/her dependents
GATE 2009 · MCQ · 2 marksQ21 · page 392 of the book
Let R and S be relational schemes such that R = {a, b,
c} and S = {c}. Now consider the following queries on
the database:
         1  πR-S(r) -πR-S(πR-S(r) × s-πR-S,S(r))

         2. {t|t∈πR-S(r) ∧∀u∈s(∃v∈r(u= v[S] ∧t=
v[R-S]))}

        3. {t|t∈πR-S(r) ∧∀v∈r(∃u∈s(u= v[S] ∧t=
v[R-S]))}

4. Select R.a, R.b

  From R, S
 Where R.c = S.c

Which of the above queries are equivalent?
  • (a)1 and 2
  • (b)1 and 3
  • (c)2 and 4
  • (d)3 and 4
GATE 2007 · MCQ · 2 marksQ25 · page 393 of the book
Information about a collection of students is given by
the relation
studInfo(studId, name, sex).

The relation enroll(studId, courseId) gives which
student has enrolled for (or taken) what course(s).

Assume that every course is taken by at least one male
and at least one female student.

What does the following relational algebra expression
represent?

πcourceId ((πstudId (σsex = 'female' ( studInfo )) ×
             πcourseId ( enroll )) - enroll )
  • (a)Courses in which all the female students are enrolled
  • (b)Courses in which a proper subset of female students are enrolled.
  • (c)Courses in which only male students are enrolled.
  • (d)None of the above.
GATE 2005 · MCQ · 2 marksQ27 · page 426 of the book
A database table T1 has 2000 records and occupies 80
disk blocks. Another table T2 has 400 records and
occupies 20 disk blocks. These two tables have to be
joined as per a specified join condition that needs to be
evaluated for every pair of records from these two
tables. The memory buffer space available can hold
exactly one block of records for T1 and one block of
records for T2 simultaneously at any point in time. No
index is available on either table. If Nested-loop join
algorithm is employed to perform the join, with the
most appropriate choice of table to be used in outer
loop, the number of block accesses required for reading
the data are  .
  • (a)800000
  • (b)40080
  • (c)32020
  • (d)100
GATE 2005 · MCQ · 2 marksQ28 · page 426 of the book
A database table T1 has 2000 records and occupies 80 disk
blocks. Another table T2 has 400 records and occupies 20
disk blocks. These two tables have to be joined as per a
specified join condition that needs to be evaluated for every
pair of records from these two tables. The memory buffer
space available can hold exactly one block of records for
T1 and one block of records for T2 simultaneously at any
point in time. No index is available on either table. If,
instead of Nested-loop join, Block nested-loop join is used,
again with the most appropriate choice of table in the outer
loop, the reduction in number of block accesses required
for reading the data will be
  • (a)0
  • (b)30400
  • (c)38400
  • (d)798400

Self-check

Question 1

How many tuples does the full outer join have if the inner join has 1010 tuples, 44 tuples of RR and 33 tuples of SS are unmatched?

Show answer

10+4+3=1710 + 4 + 3 = 17.

Question 2

Express R÷SR \div S with the basic operators.

Show answer

πX(R)−πX((πX(R)×S)−R)\pi_X(R) - \pi_X((\pi_X(R) \times S) - R).

Question 3

Why is σp(R×S)\sigma_p(R \times S) with a join condition better evaluated as a join?

Show answer

The product creates all ∣R∣∣S∣|R||S| pairs first; the join produces only the matching pairs.

Question 4

Is πA(R∪S)=πA(R)∪πA(S)\pi_A(R \cup S) = \pi_A(R) \cup \pi_A(S)?

Show answer

Yes: projection distributes over union (unlike difference and intersection).

Revision card

One-screen revision

  • Outer joins keep unmatched tuples (NULL padding); semijoin keeps matching tuples of one side.
  • Division = 'for all': πX(R)−πX((πX(R)×S)−R)\pi_X(R) - \pi_X((\pi_X(R) \times S) - R).
  • Optimise: split, push σ down, σ×→⋈, small joins first, push π with join attributes.
  • Equivalent plans, different costs.

References

  • ·Silberschatz, Korth, Sudarshan, Database System Concepts (7th edition), Sections 2.6 (additional relational-algebra operations) and 16.2 to 16.4 (equivalence rules and heuristic optimisation)
  • ·Elmasri, Navathe, Fundamentals of Database Systems (7th edition), Sections 8.4 (additional operations) and 19.1 to 19.3 (query processing and heuristic optimisation)

Verification

scripts/enum-checks/db_algebra.py: left, right and full outer joins (NULL-free data for the full join, NULL-containing data for left and right), semijoin, grouping with COUNT, SUM and MAX, and division equal the SQL forms (LEFT/RIGHT/FULL JOIN, EXISTS, GROUP BY, double NOT EXISTS) executed by SQLite on random relations; the division identity R / S = pi(R) - pi((pi(R) x S) - R) holds on 300 random instances; the animation of the outer joins, the division and the plan sizes were recomputed with SQLite (Student x Enrolled has 20 tuples, 4 survive the selection; pushing the selection gives 2 + 4 tuples; joining first gives 5 + 4); the true equivalences (selection over union, difference and product, projection over union) hold on 300 random instances and witnesses show that projection does not distribute over difference or intersection. The optimisation rules are the standard heuristics, quoted. Textbook chapter references are from memory. SECOND PASS (2026-11-02, done by the assistant, not a human check): every Self-check question was solved before the printed answer was read and all agreed; the definitions, worked examples, cheat box and traps were read claim by claim and re-derived against the textbook definitions and the sample database. No defect found. Status raised to self-checked; verified needs a textbook or human check.

last verified: never