datarekha

Tuple Relational Calculus

Instead of writing the recipe step by step, just describe the dish — TRC is the declarative twin of relational algebra, the same power in different clothes.

6 min read Intermediate GATE DA Lesson 67 of 122

What you'll learn

  • TRC is declarative — say WHAT tuples you want, not HOW to compute them
  • The form { t | predicate(t) }, with ∃ and ∀ ranging over tuples of relations
  • RA and TRC have the same expressive power for safe queries — same language, different style
  • Reading a TRC expression: every quantified variable is a tuple; dot into its attributes

Before you start

The last lesson ended wondering whether you could describe the rows you want instead of computing them step by step — and yes, you can. Think how you order coffee. Recipe style: “grind 18 grams, brew at 93°C for 28 seconds, pour 36 grams of milk on top.” Or declarative: “a cappuccino, please.” Both get you the same drink. Relational algebra was the recipe; tuple relational calculus (TRC) is the menu — you describe what you want and leave the steps to the database. That “describe, don’t compute” idea is exactly why SQL feels the way it does: SQL is the declarative style made practical, so getting comfortable reading TRC is really practising the mindset behind every query you will ever write.

The form is short:

{ t  |  predicate(t) }

Read it: “the set of all tuples t such that the predicate holds.” The predicate uses logical connectives (, , ¬) and the quantifiers (“there exists”) and (“for all”) over tuples drawn from relations.

RA vs TRC — the same query, two styles

Relational Algebra — HOWπ_name( Student ⋈ σ_cid=“CS101”(Enroll))filter, join, project — a recipeTuple Calculus — WHAT{ t.name | ∃ s ∈ Student, ∃ e ∈ Enroll ( t.name = s.name ∧ s.id = e.sid ∧ e.cid = “CS101” ) }describe the rows you want — a menuSAME ANSWERRA and TRC have the same expressive power for safe queries.
RA tells the database the steps; TRC tells it the goal. The optimiser bridges them.

Read the TRC side carefully. There is an output tuple variable t, and the predicate introduces two more tuple variables — s ranging over Student and e ranging over Enroll. We then constrain them: t.name = s.name (the output’s name is from a Student), s.id = e.sid (that Student is the one in the Enroll row), and e.cid = "CS101". The set of all such t.name is the answer — the same set of names the RA expression on the left produces.

Worked example — names of students in CS101

Schemas: Student(id, name), Enroll(sid, cid). Return names of students enrolled in CS101.

TRC:

{ t.name | ∃ s ∈ Student, ∃ e ∈ Enroll
           ( t.name = s.name ∧ s.id = e.sid ∧ e.cid = "CS101" ) }

RA:

π_name( Student ⋈ σ_cid="CS101" (Enroll) )

Both walk through the same logical join: a Student row with an Enroll row whose cid is CS101. RA names the steps; TRC names the constraints. Codd’s theorem guarantees they have the same expressive power for safe queries — anything one can compute, so can the other.

A “for all” in TRC

What about “students enrolled in EVERY course”? Use the quantifier directly:

{ s.name | ∃ s ∈ Student
           ( ∀ c ∈ Course
             ( ∃ e ∈ Enroll ( e.sid = s.id ∧ e.cid = c.cid ) ) ) }

Read it: a student s such that for every course c, there exists an Enroll row matching s.id to that c.cid. This is the same shape as relational division A ÷ B from the previous lesson — is the hallmark of for-all queries, in either notation, and TRC simply writes the quantifier out loud.

How GATE asks this

The pattern is always the same MCQ: an expression like { t.x | ∃ r ∈ R (…) } is given and four English sentences are options. You translate by reading the introduction of each tuple variable, the joining predicates between attributes, and any equality with a constant. The right English sentence is usually a one-liner.

A question to carry forward

TRC shows the declarative idea in its purest, most mathematical form — quantifiers, predicates, set braces. But you would never hand a colleague { t.name | ∃ s ∈ Student … } and call it a query. The world settled instead on a friendlier dialect of this very idea, one dressed in English-like keywords: SELECT, FROM, WHERE, GROUP BY. Here is the thread onward: how does that practical declarative language — SQL — actually compute a result by hand, and how do you trace a query with grouping and aggregation down to the exact rows and numbers it returns?

In one breath

  • TRC is declarative — say what tuples you want, not how to compute them. RA is the recipe; TRC is the menu.
  • Form: { t | predicate(t) } — “all tuples t where the predicate holds,” using ∧ ∨ ¬ and the quantifiers (exists) and (for all) over tuples of relations.
  • RA ≡ TRC in expressive power for safe queries (Codd’s theorem) — same answers, different style. in TRC = division in RA (both encode “for-all”).
  • Variables are tuples: always dot into attributes (s.name, never bare name).
  • Safe queries only — a pure complement like ¬ s.name = "Asha" over an infinite domain is unsafe and excluded.

Practice

Quick check

0/5
Q1Recall: which statements about TRC and RA are TRUE? (select all that apply)select all that apply
Q2Trace: what does this TRC expression return? Schema Emp(id, name, dept). `{ t.name | ∃ e ∈ Emp ( t.name = e.name ∧ e.dept = 'CS' ) }`
Q3Apply: which RA expression is equivalent to `{ t.name | ∃ s ∈ Student ( t.name = s.name ∧ s.marks > 80 ) }`? Schema Student(id, name, marks).
Q4Apply: what does this TRC expression return? Schemas Student(id, name), Enroll(sid, cid). `{ t.name | ∃ s ∈ Student ( t.name = s.name ∧ ∀ c ∈ Enroll ( c.sid ≠ s.id ) ) }`
Q5Create: which TRC expression returns 'names of departments that have at least one employee'? Schemas Emp(id, name, dept), Dept(dname, location).

Sign in to track your progress

Completed lessons, your XP, level, and streak save to your account — it's free and takes a few seconds.

Practice this in an interview

All questions

Related lessons

Explore further

Skip to content