skip to content

questions

19

What is the Cartesian product of two relations, and how are the theta-join and equi-join defined in terms of it?

level: juniorimportance: must knowfreq 60%

answer

  1. product = every pairing, |R| * |S|
  2. theta-join = sigma[theta](R x S), derived not primitive
  3. equi-join = equality-only theta
  4. equality hashes and sorts; inequality does not
  5. logical definition, never a literal execution recipe

basics

~20 s

The Cartesian product pairs every tuple of one relation with every tuple of the other, producing a relation with the combined attributes and a cardinality equal to the product of the inputs. A theta-join is that product filtered by a predicate; an equi-join is a theta-join whose predicate uses only equality comparisons.

solid answer

~50 s

**Cartesian product** (`R x S`) forms every possible pairing: schema is the union of both attribute sets, cardinality is `|R| * |S|`. It is unconditional, so it is almost never what a query wants on its own. **Theta-join** is defined as selection applied to the product: `R JOIN[theta] S = sigma[theta](R x S)`, where theta is any predicate over both sides — equality, inequality, ranges, arbitrary boolean combinations. **Equi-join** is the special case where theta is a conjunction of equality comparisons between attributes of the two sides. It matters because equality is the only condition that hash- and merge-based physical strategies can exploit; non-equality theta-joins generally force a nested-loop shape. Two points to add: - The definition is *logical*, not physical. No engine materialises the product and then filters; it uses index lookups, hashing or merging to produce only qualifying pairs. - If the product's attribute names collide, a rename is required first, since a relation cannot have two attributes of the same name.

code

text · 3 lines
text
R x S                          -- every pairing, |R|*|S| tuples
sigma[ R.b < S.d ] (R x S)     -- theta-join, non-equality predicate
sigma[ R.a = S.c ] (R x S)     -- equi-join; both R.a and S.c remain

go deeper

for a junior

State the product's definition and cardinality, then that a theta-join is a product with a filter and an equi-join is the equality-only case.

for a middle

Add that theta-join is derived rather than primitive, that both join columns survive an equi-join, and why attribute-name collisions force a rename.

for a senior

Explain that the definition is logical and that the identity is what licenses predicate pushdown and free join reordering, plus why equality keeps more evaluation strategies open.

for a principal

Discuss selectivity estimation as the practical consequence of the definition, and when a deliberate product is the right modelling tool for grid or parameter expansion.

## Cartesian product The Cartesian product `R x S` combines every tuple of `R` with every tuple of `S`. If `R` has attributes `(a, b)` and `S` has `(c, d)`, the result has `(a, b, c, d)`, and if `R` has 1,000 tuples and `S` has 5,000, the result has 5,000,000. There is no condition and nothing is filtered — the operator's whole job is to make every combination available so a later operator can choose among them. Two requirements follow from the relational model itself: - **Distinct attribute names.** A relation's attributes form a set of names, so if `R` and `S` share a name the product would be ill-formed. A rename must be applied first. This is why joining a relation to itself always involves renaming. - **Closure.** The result is a relation, so products compose with every other operator. The product is a *primitive* operator of the basic algebra — one of Codd's original five. Everything in the join family is built on top of it. ## Theta-join A theta-join is exactly a product followed by a selection: ``` R JOIN[theta] S = sigma[theta] ( R x S ) ``` `theta` may be any predicate that references attributes of either side: `R.a = S.c`, `R.b < S.d`, `R.a = S.c AND R.b <> S.d`, a range overlap test, a distance comparison. Because it is defined by composition, theta-join is a **derived** operator, not a primitive. That is a distinction interviewers like: the join is convenience notation over product and selection, whereas the product itself cannot be built from anything simpler. Cardinality intuition: the theta-join result is somewhere between zero tuples (nothing satisfies the predicate) and `|R| * |S|` (everything does). The fraction that survives is the predicate's **selectivity**, and estimating it is the core problem of query optimization. ## Equi-join An equi-join is a theta-join where `theta` is a conjunction of equalities between attributes of the two relations, such as `R.dept_id = S.id`. Almost every join in a normalized OLTP schema is an equi-join, because joins follow foreign keys and a foreign key relationship is an equality relationship. Why the distinction earns its own name: equality has structure that inequality does not. Equal values hash to the same bucket and sort to the same position, which is what makes it possible to find matching pairs without examining every combination. A predicate like `R.b < S.d` offers no such handle in general — the matching set for each tuple is a range rather than a point — so non-equality joins tend to degrade toward examining many more combinations. The logical definition is identical in both cases; the difference is entirely about what strategies remain available underneath. An equi-join keeps **both** joined attributes in its result — `R.dept_id` and `S.id` both appear, holding equal values. Removing the redundant one requires a projection; the natural join is the variant that does this automatically. ## Logical definition versus physical evaluation The defining equation `sigma(R x S)` describes *what the answer is*, not how to compute it. Taken literally it would be disastrous: a join of two million-row tables would materialise a trillion intermediate tuples. Real engines never do this. They use the predicate to avoid generating non-qualifying pairs in the first place, and the physical strategies for doing so are a separate subject from the algebra. The algebraic identity still matters, though, because it is what licenses the optimizer's most valuable rewrites. Since a join is a selection over a product, and selection is commutative with itself, predicates can be split and pushed down; since inner join is commutative and associative (inherited from the product plus a conjunctive predicate), the optimizer may enumerate join orders freely. Those two facts come directly from the definition. ## When a Cartesian product legitimately appears Unconditional products are usually a symptom — a forgotten join predicate, producing a result that is both enormous and meaningless. But they have real uses: - Generating combinations deliberately: every product crossed with every region to build a complete grid before an outer join and aggregation fills in the zeros. - Joining a one-tuple relation of constants or parameters onto a query. - Cross-joining a small generated series to expand rows. An optimizer that reports a product in a plan for a query that named a join condition is telling you the condition could not be applied where you expected — often because it references a third relation or was written in a way that prevents it from being used as a join predicate. ## Interview framing Give the definitions crisply, state the cardinality arithmetic, note that theta-join is derived while product is primitive, and add the equality-versus-inequality point about which strategies stay available. Finishing with "the definition is logical, not a recipe" shows you understand why the identity matters to the optimizer rather than to the executor.

  • Is the theta-join a primitive operator of relational algebra?
    No. It is derived: by definition it equals a selection applied to the Cartesian product, and the product plus selection are the primitives. The join gets its own notation because it is overwhelmingly the common case and because engines implement it as a single operator rather than as two.
  • Why does the equality-versus-inequality distinction matter if both are just selections over a product?
    Logically it does not — both denote the same kind of filtered product. It matters underneath, because equality lets matching tuples be located by hashing or by position in a sorted order, so qualifying pairs can be produced without enumerating all combinations. An arbitrary inequality gives no such handle, so far more combinations must be considered.
  • You see an unconditional Cartesian product in a plan for a query that specified join conditions. What does that suggest?
    Usually that the condition could not be used as a join predicate between those two relations — it may reference a third relation, so the two must be combined before it can be applied, or it may have been written in a form the optimizer cannot treat as a join condition. Occasionally it is deliberate, when one side is a single row or a tiny generated set and crossing is genuinely the cheapest option.

saying these in an interview costs you the question

  • Believing the engine literally materialises the Cartesian product and then filters it
  • Thinking a Cartesian product is always a bug rather than sometimes deliberate
  • Claiming theta-join is a primitive operator alongside product and selection
  • Assuming an equi-join removes the duplicate join column automatically — that is natural join
  • Saying inequality joins are impossible rather than merely more expensive

context

open as a page

In relational algebra, what does the selection operator σ (sigma) do to a relation, and how does a conjunctive predicate σ over "p AND q" relate to applying two selections one after the other?

level: juniorimportance: must knowfreq 68%

basics

~10 s

Selection σ_p(R) keeps exactly the tuples of relation R that satisfy predicate p. The schema is unchanged — it filters rows, never columns. Conjunctions cascade: σ_{p∧q}(R) = σ_p(σ_q(R)) = σ_q(σ_p(R)).

open as a page

Before you can take the union or the difference of two relations in relational algebra, what must be true of them? Explain what "union compatibility" means and what breaks without it.

level: juniorimportance: must knowfreq 58%

basics

~20 s

The two relations must be union-compatible: same number of attributes, in corresponding positions, with compatible types. Without that, the result would have no well-defined heading, so the expression is simply invalid — not merely wrong at runtime.

open as a page

What are the semi-join and anti-join operators, and how does each differ from an ordinary inner join in the shape and the cardinality of its result?

level: middleimportance: must knowfreq 45%

basics

~20 s

A semi-join returns the tuples of its left relation that have at least one match on the right; an anti-join returns those with no match. Both return only the left relation's attributes and never duplicate a left tuple, unlike an inner join which widens the schema and can multiply rows.

open as a page

What does the projection operator π (pi) do in relational algebra, and why can projecting a relation return fewer tuples than it read?

level: middleimportance: must knowfreq 62%

basics

~20 s

Projection π_{A,B}(R) keeps only the listed attributes of every tuple, producing a relation with a narrower heading. Because a relation is a set, tuples that become identical after the other attributes are dropped collapse into one — so the row count can shrink.

open as a page

How do the relational algebra's union, intersection and difference map onto SQL's UNION, INTERSECT and EXCEPT, and where does SQL's behaviour differ from pure set semantics?

level: middleimportance: must knowfreq 55%

basics

~20 s

UNION, INTERSECT and EXCEPT correspond to ∪, ∩ and −, and all three eliminate duplicates, matching set semantics. The ALL variants (UNION ALL, INTERSECT ALL, EXCEPT ALL) keep multiplicities instead, giving bag semantics the algebra has no equivalent for.

open as a page

How do the SQL predicates IN, EXISTS and NOT EXISTS correspond to the semi-join and anti-join operators of relational algebra, and where does that correspondence break down?

level: seniorimportance: must knowfreq 48%

basics

~20 s

An uncorrelated IN subquery and a correlated EXISTS both denote a semi-join: keep outer rows that have at least one match. NOT EXISTS denotes an anti-join. NOT IN does not cleanly denote an anti-join, because an unknown comparison prevents any row from qualifying once the subquery yields a null.

open as a page

In relational algebra, what does the rename operator (rho) do, and why is it required before a relation can be joined to itself?

level: juniorimportance: should knowfreq 40%

basics

~20 s

Rename gives a relation, or its attributes, new names. Relational algebra identifies attributes by name, not position, so a self-join needs two differently named copies of the same relation; rename supplies them and also resolves attribute-name clashes so the result is a legal relation.

open as a page

What kind of question does the relational algebra division operator answer, and given a relation of student enrolments and a relation of required courses, what exactly does dividing one by the other return?

level: middleimportance: should knowfreq 38%

basics

~20 s

Division answers universally quantified "for all" questions. Enrolments(student, course) divided by Required(course) returns the students who are enrolled in every required course — the students whose set of courses is a superset of the divisor's courses.

open as a page

Classic relational algebra has no way to compute a count or a sum. What does the extended grouping-and-aggregation operator add, how is its result defined, and why can the five basic operators not express it?

level: middleimportance: should knowfreq 42%

basics

~20 s

Grouping/aggregation (written gamma) partitions a relation by grouping attributes, applies aggregate functions such as COUNT, SUM, MIN, MAX, AVG to each partition, and returns one tuple per group. The basic operators only select, combine and drop existing tuples and attributes; they can never compute a new value from a set of tuples.

open as a page

What does the natural join operator do with attributes that both relations happen to share, and why do practitioners consider it risky in a long-lived schema?

level: middleimportance: should knowfreq 42%

basics

~20 s

Natural join equi-joins on every attribute the two relations share by name, then keeps just one copy of each shared attribute. Because the join condition comes from the schema rather than the query, adding or renaming a column later silently changes which attributes are matched and therefore changes the result.

open as a page

Relational algebra is defined over sets, while a table in a SQL database is a multiset (bag). What practical differences does that create when you translate a projection into a SELECT column list?

level: middleimportance: should knowfreq 48%

basics

~20 s

In set semantics, projecting drops duplicates automatically. SQL tables are bags, so a plain column list keeps every duplicate row and you must add DISTINCT to match the algebra. Duplicate elimination then costs a real sort or hash step.

open as a page

Relational algebra treats set difference as a primitive operator but intersection as a derived one. Show how intersection can be expressed using only union and difference, and explain why having a minimal set of primitive operators matters.

level: middleimportance: should knowfreq 40%

basics

~20 s

Intersection is derivable: R ∩ S = R − (R − S). A minimal primitive set (selection, projection, union, difference, product, rename) makes it easy to prove properties of the whole algebra and to define the expressive-power baseline that "relationally complete" languages must meet.

open as a page

Why is the outer join treated as an extended relational-algebra operator rather than something derivable from the basic operators, and what does it do with tuples that find no match on the other side?

level: seniorimportance: should knowfreq 40%

basics

~20 s

An outer join keeps dangling tuples — those with no matching partner — and pads their missing attributes with null. Basic relational algebra has no null value and no operator that invents one, so outer join needs both an extension to the value domain and an operator definition of its own.

open as a page

A colleague rewrites an existential subquery into an inner join, claiming it is 'the same thing but simpler'. Under what conditions does that rewrite change the answer, and what has to be added to make it equivalent?

level: seniorimportance: should knowfreq 38%

basics

~20 s

It changes the answer whenever an outer row matches more than one inner row: the semi-join returns that row once, the inner join returns it once per match. Equivalence requires either a proof that the join key is unique on the inner side, or an explicit duplicate elimination on the outer row's identity after the join.

open as a page

An engine wants to apply a relational-algebra projection before a selection instead of after it. Under what condition is that rewrite safe, and what does it buy?

level: seniorimportance: should knowfreq 38%

basics

~20 s

Safe only if every attribute the selection predicate references survives the projection. Otherwise the filter has no column to test. When safe, projecting first narrows tuples early, cutting memory and I/O through the rest of the plan.

open as a page

To reconcile two datasets you compute the difference in both directions — rows in A not in B, and rows in B not in A. What properties of set-difference semantics can make that result misleading, and how do you make the comparison trustworthy?

level: seniorimportance: should knowfreq 42%

basics

~20 s

Set difference deduplicates, so count mismatches vanish; it compares whole rows positionally, so a column-order or type-coercion difference makes everything look different; and it says which rows differ, not which columns. Compare on a key with a value-level check instead.

open as a page

Relational division is not a primitive operator. Show how it is derived from projection, Cartesian product and set difference, and explain why the derivation is naturally read as 'build the counterexamples and subtract them'.

level: seniorimportance: nice to knowfreq 25%

basics

~20 s

Take all candidates (project the dividend onto the non-divisor attributes), pair every candidate with every divisor value via Cartesian product, subtract the pairs that actually exist in the dividend — what remains are the missing pairs. Project those onto the candidate attributes to get the disqualified candidates, and subtract them from all candidates.

open as a page

Real query engines evaluate bag (multiset) algebra rather than the set algebra of the textbook. Which algebraic laws stop holding once duplicates are preserved, and how does that constrain the rewrites an optimizer is allowed to perform?

level: principalimportance: nice to knowfreq 30%

basics

~20 s

In bag algebra each tuple carries a multiplicity. Projection no longer removes duplicates, union adds multiplicities instead of merging, and idempotence, absorption and some distributive laws fail. An optimizer may therefore only insert or remove duplicate elimination where the enclosing context is insensitive to multiplicity.

open as a page