Relational Algebra: Select, Project, and Joins
Prerequisite Knowledge
This lecture builds on the following concepts from earlier lectures. If any feel unfamiliar, review the linked notes before proceeding.
Previously Covered in This Subject
- Relational algebra and why it exists — covered in Lecture 6 (Relational Algebra: The Mathematical Foundation of SQL)
- Select and project as row and column filters — covered in Lecture 6
- Relations, tuples, and domains — covered in Lecture 3 (The Relational Model)
- The four properties of a good database schema — covered in Lectures 4 and 5 (Normalization)
- Data storage, retrieval, and querying — covered in Lecture 1 (Introduction to Database Systems)
7.1 Why Relational Algebra Exists
7.1.1 Data at the Heart of Every Application
Hook: One person can help a handful of others face to face. What changes when a single person can build one application that thousands, or a million, people use every day? Everything in this course flows from that idea.
This session is practical, and it starts from the premise of technology itself. As computer science students we want to influence people and add value to their lives. In person, one person can help a limited number of others. With the power of technology, one person can influence, impact, and add value to an order of magnitude more people — that is the entire premise of the subject. The applications we build come in many shapes: desktop applications, mobile applications, enterprise applications, and so on. In every one of them, data plays a central role in the heart of the application, whether the app directly solves a problem or simply delivers a personalized user experience.
Real-world: think of supply chains, railways, airlines, banking applications, agriculture, automobiles, or edtech — every one of them runs on data. An application is a complete architecture: there are microservices and APIs, many languages, test cases, a front end with a visual experience, something to be deployed somewhere, and integration between front end, back end, services, and APIs. The database is one particular component inside that architecture, and it has its own role to play.
Why a whole course for one small component? Some people say the database is not that important, so why does a whole course exist for just a small piece of an application? The answer is that database handling is a proper science. If we store and retrieve data properly and allow many, many people to access it in a concurrent manner, the application can scale to a larger level, give a better experience, and solve a meaningful problem for the user. That is why the database science exists — the science exists precisely so that the application can grow and solve real problems.
7.1.2 From a Good Schema to a Language for Retrieval
Before we touch any symbols, fix the three words that describe the layers of a database system. A database is primarily the schema and the data together — the blueprint (schema) plus the actual stored rows (data). A database management system (DBMS) is the application that helps us store and retrieve data. The database system is the complete package — the database, the real-time data, and the DBMS applications taken together.
The design journey is already familiar: a user gives a requirement ("this is what I want to create, this is what I want to store"), we create an ER diagram (entity relationship diagram), and we convert it into a basic relational schema. At a basic level, that is good enough — for a startup in its prototype phase that wants to raise money and go commercial, an ER diagram and a relational schema are fine to go ahead with.
Real-world: as soon as we want a commercial-level application that really scales, we need a good database schema. "Good" rests on the four properties discussed earlier: proper semantics (anyone working with the data knows what the database means), least redundancies and anomalies, least null entries, and minimum spurious tuples created. The entire science of normalization — first normal form, second normal form, third normal form, BCNF, 4NF — makes sure there is less and less redundancy, which means fewer and fewer functional dependencies in a relation.
Now the schema is proper, so we need to store data in it and retrieve data from it. That requires a proper language to talk to the data. That science is relational algebra — the mathematics for it — and SQL, the programming part for it.
7.1.3 Why Mathematics, and Why Relational Algebra Specifically
In relational algebra we mathematically represent what the user wants to retrieve. It is not about storage; it is mostly about the retrieval part. Why relational algebra and not just SQL? SQL is the programming part; relational algebra is the mathematical part, and mathematics is the basis of most of computer science, if not all of it.
Why math is the right language for retrieval. If we talk about something for two hours, two people's words may differ, and ambiguity creeps in. But when an equation is written in mathematical format, the equation is completely unambiguous — the way any object moves, the properties of any object. A programming language, likewise, needs to be deterministic: if a command can do two things, the computer cannot understand it; it becomes non-deterministic, which is not good. Mathematics is the heart of that certainty. The same equation means the same thing to every reader; the same query expression returns the same answer on the same data, every single time.
Relational algebra specifically matters because when we want to optimize SQL queries, ultimately we think about them and use them in a relational algebra manner. Even if many of us will not write relational algebra day to day, the way relational algebra correlates with SQL can be useful in other areas of life — management, sales, or any field where the logic of retrieval applies.
7.1.4 A Vocabulary Warning
Warning: the same word can mean two different things. There is an important point to understand before we start: some terms in SQL and relational algebra look similar, but many times their internal interpretation is different. When learning a database course, always check which context a key term is used in. The word "select" means one thing in relational algebra (filtering rows) and something different when we program in SQL (where SELECT also chooses the columns that come back). Keep that warning in mind throughout — mixing the two meanings is one of the most common beginner confusions in this topic.
7.1.5 The Operator Roadmap
Relational algebra primarily works with these symbols: select, project, rename, union, Cartesian product, intersection, set difference, joins, and division. Besides these, there are aggregation functions such as minimum and maximum, and some outer joins, which we will discuss too.
The session is organized in three stages: information, education, and skill. The handout you already have provides the information — if you know how the symbols work, that is exactly the information being provided. Education follows in the few minutes where we explain how select works, how project works, how rename works. And when you practice from the lab sheets, that adds skill. The instructor takes you from zero level to the next level, and you are asked to participate and practice while the session runs. If you are left behind, or if you have errors you want resolved, type them in the chat box. The prerequisite is that you should not know anything. And those who are well versed in SQL programming are asked to help others — whatever we give, we will get; when we encourage others to learn, we learn heavily as well.
Q: Why does a whole course exist for just this small piece of an application? A: Because data handling is a proper science. If the data is stored and retrieved properly, and many people can access it concurrently, the application can scale to a larger level, give a better experience, and add meaningful value. That is where the weightage of the database comes from — the science exists precisely so that the application can grow and solve real problems.
Recap: Data sits at the heart of every application; a good schema comes from normalization; and retrieval needs an unambiguous language. Relational algebra is that mathematics — the same mathematics every real DBMS's query optimizer works in. In this lecture we learn its operators one by one, starting with the two unary ones: select (rows) and project (columns).
Real-world: when you run a slow SQL query in a production system and the DBA shows you the "execution plan", what you are looking at is a relational algebra expression that the DBMS rewrote and priced. Understanding this topic is exactly what makes those plans readable — and why this science is taught before SQL is written by hand.
7.2 Select
7.2.1 What Select Does
Hook: You have a table with thousands of rows and you want only the few rows that matter. Which operator keeps rows and leaves every column untouched? That operator is the first one we meet: select.
The select operation is a row filter. Think of a sieve held over the table: it lets some rows fall through and keeps the rest out. We start with a relation — for example, a student relation. The student relation has attributes such as ID and name (it may also have phone number, email ID, and address), and it is populated data: the relation contains many tuples, many entries in row format or record format. Now we want only those tuples in which the ID number is 1234, and we do not want to remove any column. The predicate (the condition) says that ID is equal to 1234:
Formalize the select operation. The general shape is
The symbol (sigma, the Greek letter "s") denotes the select operator. The subscript is a predicate — a condition that each tuple is checked against, one row at a time. A predicate is a Boolean expression built from clauses of two forms: attribute compared to a constant (e.g., ) or attribute compared to another attribute (e.g., ), using the comparison operators . Clauses can be combined with AND, OR, and NOT to form compound conditions such as . A tuple is kept exactly when the condition evaluates to TRUE for that tuple; tuples that evaluate to FALSE are discarded. The result of a select is a new relation with the same attributes (same degree) as — select never adds or removes columns.
The professor's own words: "This particular expression would take a relation from student and result into all the rows which satisfy this particular condition — that ID number is equal to 1234." That is all select does: it keeps rows that satisfy the predicate, and every column stays.
7.2.2 Worked Examples on the Company Schema
For the rest of the session we practice on one particular schema, which we use every time: the employee relation has first name, middle name, last name, and other attributes (including social security number, salary, department number, and supervisor's social security number), and there are other relations such as department, project, dependent, and department locations. The lines in the schema represent the foreign keys.
Example 1 — Select the employee tuples whose department number is equal to 4.
First, read the requirement against the whole schema. The department number appears in the department locations relation, in the department relation, in the project relation, and in the employee relation. What does the user want? The user said "employee tuples," so the only relation that matters is employee — the answer is easy:
Read the expression aloud: "select from Employee the tuples where Dno equals 4." The predicate is applied to every employee row one by one; the rows of employees working in department 4 pass the test, all other rows are dropped, and every attribute of the surviving rows stays in the result. The result is the employee relation restricted to the department-4 employees, with all columns intact. Sense-check: the user asked for employee tuples, so the answer must be a relation over the same attributes as Employee — which is exactly what a select returns.
Example 2 — Select the employee tuples whose salary is greater than \$30,000.
This is even simpler, because salary is already an attribute of the employee relation:
The predicate is a comparison clause of the form attribute–operator–constant. Each employee row is tested: keep the row if its salary exceeds 30,000, drop it otherwise. The result contains every employee earning more than \$30,000 — again with the full set of employee columns. Sense-check: the boundary matters — an employee earning exactly \$30,000 does not satisfy "greater than" and is left out.
The thought process for relational algebra and SQL is mostly the same: understand the user's requirement, go back to the relational schema, see which attributes and which relations are involved, realize in English what we want to do, and then express it in relational algebra or in SQL. The way of thinking remains the same; only the expression language changes.
Assumptions and scope of select. Select is a unary operation: it takes exactly one relation as input. The condition is checked per tuple, so a selection condition can never compare two different rows of the same table (that needs a join, which we meet later). The result can only shrink: the output has at most as many tuples as the input — the fraction of rows that pass the predicate is called the selectivity of the condition, a word we will meet again in query optimization. And because select works on any relation, it can be applied to the result of another operation — expressions compose.
7.2.3 Student Questions and Answers
Q: What if the attribute is not there in that particular relation? For example, what if the salary attribute is not given — how can we compare? A: Hold on to that thought — we will get there within ten minutes. If the attribute is not present in a relation, we use either the cross product or the natural join. There are options. We need to be open to the fact that we may have to use two, three, or even four relations to get what the user is asking for. The answer will come in this session itself.
Q: So project works on the attributes and select works on the rows — select filters out a few rows, and project filters out a few attributes on the column side? A: Correct. If the user wants to filter only on the attribute side, we use project. If the user wants to filter only on the row side, we use select. If the user wants both — keep only the rows that satisfy a condition, and of those rows keep only certain columns — we use both operations together.
Recap: Select is the row filter — sigma , one relation in, a predicate on the rows, all columns preserved. It is the operation you reach for whenever the requirement names a condition on rows and no columns need to go. Next comes the partner operation: project, which filters the other direction, on the column side.
Real-world: in SQL, the select operation is written as the WHERE clause — SELECT * FROM Employee WHERE Dno = 4 is the SQL spelling of . Every time a banking app shows "your transactions this month" or a railway system filters trains by departure station, some optimizer has translated a WHERE condition into exactly this relational algebra operator.
7.3 Project
7.3.1 What Project Does
Hook: Select kept all the columns and trimmed the rows. What if the user wants the opposite — every row, but only a few columns? That is the second unary operator: project.
The project operation works on the attributes. It is the operation you may already have guessed, the pi symbol . We list the attributes we want to reduce the relation to, and the result contains only those attributes:
This expression results in only one attribute — the ID — from the student relation. It may be possible that ID is unique, or it may not be unique; but whatever starts off with this relation ends off with a relation, and everything is unique in a relation. That is a basic property: there is no repetition in the final relation. Project reduces the number of columns; select reduces the number of rows.
Formalize the project operation. The general shape is
The symbol (pi, the Greek letter "p") denotes the project operator. The subscript names the attributes we want to keep, and the result contains exactly those attributes, in the order written. Two consequences follow from the rule that the result must be a relation:
- Duplicate elimination. If the attribute list contains only non-key attributes, the same combination of values can appear in several input rows. Because a relation is a set of tuples — no two identical rows — the duplicates are removed. So the project can produce fewer tuples than it started with; the tuple count shrinks unless the projection list includes a key (a superkey), in which case no two rows could have been identical in the first place and the count stays the same.
- Composition. The output is a normal relation, so any operation can be applied to it next — including another project. In fact, projecting twice is the same as projecting once to the smaller list: whenever .
7.3.2 Worked Examples
Example 1 — A list of all employees' first name, last name, and salary.
No condition is specified; we simply want the three attributes of every employee:
Work it through on three sample rows:
| Fname | Lname | Salary | Dno | -> | Fname | Lname | Salary |
|---|---|---|---|---|---|---|---|
| John | Smith | 30000 | 5 | John | Smith | 30000 | |
| Franklin | Wong | 40000 | 5 | Franklin | Wong | 40000 | |
| Alicia | Zelaya | 25000 | 4 | Alicia | Zelaya | 25000 |
The result has the three listed attributes for every employee — all rows, no condition applied. Sense-check: the requirement says "a list of all employees", so no rows are dropped, and only the three named columns survive.
Example 2 — First name, last name, and salary of all employees who have worked in department number 5.
This combines the two expressions we just wrote. The user wants both things: the names and salary, and only for those employees whose department number is equal to 5. One way is to select first and project after:
Read it inside-out. The inner keeps the rows of employees in department 5 — say John Smith (30000) and Franklin Wong (40000), while Alicia Zelaya (25000, department 4) is dropped. That intermediate result is a relation, so the outer is applied to it exactly as if it were a plain stored table, keeping the three columns:
Result: John Smith, 30000; Franklin Wong, 40000. Sense-check: every row in the answer must belong to a department-5 employee (the select guarantees it) and must show only the three requested columns (the project guarantees it) — the composition checks out.
We discussed the other option earlier: project first and select later. Both are expressible. The key property that makes composition possible: whatever we get at the end of this portion is a relation, and just like any other relation, we can apply any operation on it — project, select, or anything else. What we get is a relation, and we apply the project with attributes to it exactly as if it were a plain relation.
Scope of project. Project trims columns and removes duplicate rows; it never filters rows by a condition — that is select's job. The two operators combine freely, but only when their order makes sense: an operation can only use attributes that are present in its input relation, so the attribute you filter on must survive the projection that happens before the filter. Project's duplicate elimination also has a cost (the system must compare rows or sort), which is why real optimizers push projections down the query tree only when the narrowed rows actually help — a preview of the optimization topic.
7.3.3 Student Questions and Answers
Q: Can we do the project first and then select later? A: Yes, we can do either thing. But if we project first and the projection drops the department number, then selecting "department number is equal to 5" from the result is meaningless: the attribute is not there at all in that final relation, so the constraint is not applied. Here, where we keep first name, last name, and salary only, we cannot filter on department number afterwards — the operation does nothing. When we select first and project after, the rows are already constrained to department 5, and then we pick the three names. The reason we used only the employee relation is that employee has every attribute we need to take action upon.
Q: Out of these two operations, which one is more efficient in terms of complexity? A: Right now the first one is not even correct — forget about efficiency. When you answer relational algebra questions, all five options you propose may be correct, and correctness is what we are checking first. After the correct answer, there is a specific topic for efficiency and optimization of queries; then we will discuss which one is more optimized. You are right that performance makes a lot of difference, but for now let us worry only about correctness.
Q: If we select on a column that we removed in the projection, won't it return a null value or something? A: No, it does not matter. The query simply discards the constraint — it is not applied. There is no null return; the filter just does nothing. The condition is not silently violated and no error is raised; the predicate is simply never evaluated, because the attribute it names no longer exists in the input relation.
Q: If the user also wants the department number — say the projection is first name, last name, salary, and department number — then which order is better? A: If the department number is present in both the projection and the selection, you can write either order; both attempts fetch full marks. Right now the answer is judged on correctness, not efficiency.
Q: Is there a precedence between project and select — which one executes first? A: The brackets decide it. Whatever is inside the bracket portion is executed first, and whatever result comes out of it is applied on the portion outside later. It moves from inside to outside, the same principle as BODMAS in arithmetic. In , the select inside the brackets runs first, and the project runs on its result.
Q: Is it always only one table that is passed to these operators — select and project take only one relation? A: That is the next topic: how to use more than one relation as well. Select and project do work on a single relation, but operations such as cross product, join, union, intersection, and set difference bring two or more relations together.
Q: (Comment) Doing the project first means reading only the columns we actually need; if we select more columns than we need, we are unnecessarily reading more. A: Correct — optimization-wise, project first can be better, and we will discuss optimization in a specific topic later. But if the project does not include the column you filter on, the select that follows does not refine anything; it is redundant. Efficiency is a real concern, but it only matters after the expression is correct.
Recap: Project is the column filter — pi , one relation in, an attribute list, duplicate rows removed. Select and project are the two unary operators, and they compose: the output of either is a full-fledged relation. The next operator answers the question a student asked moments ago — what happens when the attribute we need lives in a different table? That is where rename and the binary operations begin.
Real-world: every report a business runs is a projection — "give me customer name and order date", "list product and price" — followed by a selection of the rows that qualify. When a dashboard shows a filtered, narrowed table, it is executing a select-then-project chain that an optimizer will later reorder to do the filtering first, for exactly the reason discussed here: fewer rows flowing through is cheaper.
7.4 Rename
7.4.1 Renaming Relations and Attributes
Hook: The next question of the session is coming: what if the attribute we need sits in another table — or what if a table needs to talk to itself? Both cases need a way to change names. That is the third unary operator: rename.
The rename operation has the symbol rho . There are three levels of use.
First, we can rename the relation itself. If we want to rename relation to , we write , and from that point onwards the relation is named — every further query uses instead of . For example, if the relation is student and we want to call it persons:
Second, we can rename the attributes. If the student relation has two attributes, ID number and name, and we want the first one to be called ID number and the second one to be called actual name, we write the new attribute list inside the parentheses with the new relation name:
From that point onwards these attributes are renamed.
Formalize the rename operation. For a relation of degree — that is, with attributes — there are three standard forms:
The first form renames both the relation (to ) and every attribute (the -th attribute of becomes ); the second renames only the relation; the third renames only the attributes. Renaming never touches the tuples — the data rows are carried over unchanged, only the names in the schema change. Renaming is free of charge semantically; its whole value is referential: later expressions can point at the renamed relation or its renamed attributes under the new names.
Third, we can capture an expression under a name even without writing . When we apply an operation and name the result — result one, result two, result three — we can use that name later in further queries (such as applying a project on the named result). This is quite important when the same relation is applied twice in one expression: renaming lets us refer to the two copies separately.
Worked example — renaming a relation and its attributes.
Start with the student relation holding two attributes in the order (ID number, name), populated by the tuples (1234, Anand) and (5678, Bhavna). Step by step:
- Rename the relation to persons: — the same two tuples, now living in a relation called persons.
- Rename both attributes in one step: — the relation is called persons, and the second attribute is now actual name instead of name.
- Name an intermediate result for later use: after writing , the name result_1 can be used in the next line, e.g. — provided the intermediate was renamed with the new attribute name.
The result of the full chain: the single name "Anand". Sense-check: the select keeps the row whose ID is 1234, the rename gave the second attribute the name we want to project, and the projection returns that one value as a one-attribute, one-tuple relation.
Scope — why rename is needed at all. Relational algebra gives you only the names that are in the schema; if two relations share an attribute name that means the same thing (the classic case), a natural join is automatic, but if the names differ, you must rename before joining. Worse, a relation has no way to tell its rows apart if it appears twice in one expression — the self-join, used for queries like "give me every employee together with the name of their supervisor", is impossible without renaming the two copies of the employee table to different names. Rename is the plumbing that makes joins and self-references expressible at all.
7.4.2 Student Questions and Answers
Q: For the rename with attributes, the attributes we mention have to be in the same order as the relation's attributes, right? A: Yes, exactly correct. The new attribute list must follow the order of the relation's existing attributes. In , the first new name replaces the first original attribute , the second replaces the second, and so on — position by position, never by name matching.
Recap: Rename is rho — a name-changing operator that works on the relation name, the attribute list, or both, and never touches the data. Combined with the trick of naming intermediate results, it gives us the power to use the same table twice. That power is exactly what the next questions need: combining two relations, and sometimes two copies of one relation, into a single result.
Real-world: every SQL query that writes FROM Employee E, Employee M or uses aliases like AS E and AS M is doing a rename — database engines cannot join a table to itself any more than relational algebra can, so the two copies must carry distinct names. Renaming is also the standard trick for making two differently named attributes match before a natural join, which every reporting join in a data warehouse leans on.
7.5 Union, Intersection, and Set Difference
7.5.1 The Compatibility Condition
Hook: The unary operators can only work with what one table gives them. Now the questions the students asked start paying off: how do we combine two relations — and when is the combination even allowed? The first set operations answer exactly that.
The union requires that and be compatible relations: the same number of attributes, the attributes in the same order, and the same domains. For example, if the student relation has two attributes — ID number and name — and the employee relation has two attributes — say employee number and name — and the domains of both are the same and the names of the attributes are the same, then we can take their union. The same compatibility requirement applies to intersection and set difference.
Formalize the set operations. Two relations and are union compatible (also called type compatible) when they have the same number of attributes and each corresponding pair of attributes has the same domain — the same kind of values. Then:
- Union — every tuple that is in , in , or in both. Duplicate tuples are eliminated: a tuple shared by both relations appears exactly once.
- Intersection — every tuple that is in both and .
- Set difference — every tuple that is in but not in .
Union and intersection are commutative () and associative; set difference is not commutative — and are usually different relations. By convention the result carries the attribute names of the first relation ; rename is available to fix the names afterwards if needed.
7.5.2 Worked Example: Department-Five Employees or Their Supervisors
The requirement: find all the employees' SSNs who work in department number 5, or the SSNs of the supervisors who work in department number 5. The employee relation stores first name, middle name, last name, social security number, supervisor social security number, salary, and the department in which the employee works.
Worked example — union of employee SSNs and supervisor SSNs.
The setup: suppose Amido, Anant, and Shrijeet work in department 5. Their supervisors — Rajinikant, Mega, and Sayad — may work in departments 3, 9, and 25. The user still wants our employees' SSNs and also the supervisors' SSNs, because they are supervisors of department-5 employees. So we select all employee tuples who work in department 5; in that selection we have both SSN and Super_ssn. In the first part we project the SSN of the employees who work in department 5, and in the second part we project the Super_ssn from the same selection, then take the union:
Step by step:
- — keep only the rows of Amido, Anant, and Shrijeet; each row still carries both SSN and Super_ssn.
- — project the employees' own SSNs: a one-attribute list of their numbers.
- — project the supervisor numbers from the very same selection: Rajinikant, Mega, and Sayad.
- — combine the two lists; any number that appears on both sides is written once.
The result is a single column of SSNs containing the department-5 employees and their supervisors, with no repeats. Sense-check: the requirement is an "either-or" — an SSN is wanted if it is an employee of department 5 OR a supervisor of one — and the union is precisely the operator for combining two such "or" conditions into one set.
Someone might ask why we cannot simply project both SSN and Super_ssn in one projection. Because that returns pairs of values (each employee with their supervisor's number), not the single set of "either the employee's own SSN or the supervisor's SSN" that the user asked for — the either-or requirement is exactly what the union expresses. Note also that the attribute names do not matter for the union itself, but when we join later, renaming keeps the names consistent and hygienic, so it is better to rename the supervisor SSN to make it match.
7.5.3 Intersection and Set Difference
Intersection keeps only the tuples that are common to both relations. Set difference keeps the tuples that are in the first relation and not in the second.
Worked example — intersection and set difference with student and instructor.
The example: the student relation contains Johnny, Barbara, Army, Jimmy, Ernest, Susanne, and Ramesh; the instructor relation contains John, Ricardo, Francy, Susanne, and Ramesh. Susanne and Ramesh appear in both.
- Student ∩ Instructor — the tuples common to both sides: Susanne and Ramesh.
- Student − Instructor: subtract the tuples that are common with the instructor (Susanne and Ramesh) from the student side, so the output is Johnny, Barbara, Army, Jimmy, and Ernest.
- Instructor − Student: the same subtraction from the other side, so the output is John, Ricardo, and Francy.
Sense-check: the two differences share nothing with each other (a tuple cannot be left only in student and only in instructor at the same time), and the shared names appear in the intersection but in neither difference — the three results partition the combined data exactly.
The professor's analogy: "four minus two means four minus the two in the four, and we get two as the output" — but in a homogeneous set the result looks simple to compute, while in relations the subtraction removes only the shared tuples. Set difference subtracts the elements common to both and keeps only what is left on the first relation's side. Even though it is 4 − 2 = 2 in numbers, the idea here is subtract the things that are common in instructor and student, and get only the output from the student side.
Scope of the set operations. All three operations need union-compatible inputs — same number of attributes, matching domains in the same order; union over differently shaped tables is undefined. The result of every set operation is a relation, so duplicate tuples never survive the union, the intersection, or the difference. Set difference is directional: Student − Instructor is not the same as Instructor − Student, so the order of operands in the expression must follow the requirement word for word.
7.5.4 Student Questions and Answers
Q: Since we are doing a union, what happens if there are duplicates between result one and result two? A: The duplicates are filtered out at the final end, because the final answer is a relation, and in a relation a tuple cannot appear twice. Suppose the first result has an SSN and the second result also has it — it appears only once in the union output. Good question: the union is a combination of both, with duplicates removed.
Q: In a projection, if the attribute is not a primary key, there might be duplicates — will the projection remove them? A: Yes. Whatever the final answer is, it is a relation, and in a relation there are no duplicates at all — select, project, union, whatever operation we apply, what we get at the end is a relation, and relations contain only distinct tuples.
Q: Why does the supervisor result have only two rows when four employees work in department five? A: Because one supervisor can supervise several employees. The supervisor SSN is projected, and since the output is a relation, a supervisor who supervises multiple employees appears only once. Four employees can have only two distinct supervisors, and we write only the distinct ones in the relation. The same is true for the employee side: if SSN happens to be a primary key there, no duplicates exist, but even if there were, the union would remove them.
Q: Can we say that student minus instructor is really student minus the intersection of student and instructor? A: Yes — that is exactly correct, and the correct word for it is set difference. "Minus" is fine informally; set difference is the precise term. Student minus the intersection is precisely student set difference instructor — the shared tuples are removed from the student side, leaving only the students who are not instructors.
Q: Both result one and result two will have keys — is there any way to maintain the primary key in the final result? A: Forget about primary keys, secondary keys, candidate keys, and foreign keys for the next few minutes. Right now we are only talking about relations and their tuples; that science comes later. The set operations work on the tuples themselves, and the key machinery belongs to the design chapters.
Recap: Union, intersection, and set difference are the relational versions of the everyday set ideas — combine, overlap, subtract — restricted to union-compatible relations, and always returning duplicate-free relations. The union example already showed the pattern of the next question: to combine information that sits in two different tables, we need a way to pair related rows. That is what the Cartesian product begins, and what the join perfects.
Real-world: "give me customers who bought product A or product B" is a union in every CRM system; "customers who bought A but not B" is a set difference; "employees who are also managers" is an intersection. SQL spells these as UNION, INTERSECT, and EXCEPT — the same three operators, the same compatibility requirement, and the same duplicate-free results.
7.6 Cartesian Product
7.6.1 Definition and Sizes
Hook: Two relations need to be brought together, and the requirement says nothing about matching. The bluntest possible tool pairs every row of the first table with every row of the second. That tool exists — and it explodes quickly.
The Cartesian product (also called the cross product) is the brute-force way to use two relations: take the first relation and the second relation and join them in every possible combination. If the first relation has three attributes and the second relation has two attributes, and the first has four tuples and the second has five tuples, then:
- The number of attributes in the result is the sum: .
- The number of tuples is the product: every tuple of the first relation pairs with every tuple of the second, so tuples.
Formalize the Cartesian product. For a relation with attributes and a relation with attributes :
The result relation has attributes — all of 's attributes followed by all of 's, in order — and tuples, one for every combination of a tuple from and a tuple from . Written with sizes: if and , then . Two rules to remember: attributes add, tuples multiply. Unlike the set operations, the product does not require union compatibility — the two relations may be completely different shapes; that is what makes the product so general, and so wasteful.
Worked example — counting a Cartesian product.
Suppose relation has 3 attributes and 4 tuples, and relation has 2 attributes and 5 tuples.
- Attribute count: attributes in — the first three come from , the next two from .
- Tuple count: every one of the 4 tuples of pairs with every one of the 5 tuples of , giving tuples.
The result has 5 attributes and 20 tuples. Sense-check: each of the 4 R-tuples must appear in a pair with each of the 5 S-tuples — that is 4 groups of 5, which is 20 — and no attribute disappears in the pairing, so 3 + 2 = 5 columns is right.
In general, if relation has attributes and relation has attributes , the result relation has attributes through followed by through , and the number of tuples is the multiplication of the two counts — every tuple on the side combines with every tuple on the side. That is the basic idea of the cross product.
7.6.2 A Not-So-Meaningful Cross Product
Here is an example that makes little sense, deliberately: we want the cross product of employee names and dependents. Suppose we select all employees of female gender and project their first name, last name, and SSN, and then take the cross product with the dependent relation:
Worked example — a deliberately meaningless product.
Take three female employees — Alicia, Jennifer, and Joyce — and suppose the dependent relation holds two dependents: Abner and Theodore.
- — keep the female employees: 3 rows.
- — keep their names and SSNs: 3 rows, 3 attributes.
- — pair each of the 3 employee rows with each of the 2 dependent rows: rows.
The output has 6 tuples — Alicia-with-Abner, Alicia-with-Theodore, Jennifer-with-Abner, and so on — pairing every employee with every dependent, whether or not the dependent actually belongs to that employee. The output has four attributes: first name, last name, SSN, and the dependent attributes. Sense-check: the 6 = 3 × 2 count follows the "tuples multiply" rule, and the pairs are exactly the mechanical combinations — which is precisely why the result is meaningless: most of these employee–dependent pairs do not correspond to real family relationships.
Whether it makes sense or not, the cross product works exactly like that — it pairs everything with everything. The cross product is not, by itself, a meaningful relation; it produces a lot of combinations, many of them useless. What we actually want is the join operation, which turns the cross product into something meaningful — and that is the next topic.
Q: Wait — you first said the output has four tuples, then you corrected yourself. What is the tuple count of a cross product? A: I messed myself up there. Tuples multiply, they do not carry over. If there are three tuples on one side and four tuples on the other, the final result has tuples, because every tuple on one side pairs with all four tuples on the other side. The attributes add; the tuples multiply.
Scope of the Cartesian product. Alone, the product is almost never what the user wants: the number of rows multiplies, so products of large tables explode — 100,000 employees times 100,000 dependents is 10 billion rows. Its real role is as a building block: a product immediately followed by a selection that matches related values is a join, and the join exists precisely so that we never have to materialize the useless combinations in between. In practice, a bare product is executed only when the follow-up selection can be pushed into it, which the query optimizer (a later topic) handles automatically.
Recap: The Cartesian product is the everything-with-everything operator: attributes add, tuples multiply, and the result is usually meaningless on its own. It matters because the meaningful join is built on top of it — take the product, keep only the rows where a common value matches, and drop the repeated column. That is exactly the next operator: natural join.
Real-world: SQL has a CROSS JOIN that does precisely this, and database engines warn about it because a forgotten join condition silently produces one — the classic cause of queries that return absurdly many rows. When a scheduler pairs every delivery van with every route to find all possible assignments, it is running a Cartesian product and then selecting the feasible pairs.
7.7 Natural Join
7.7.1 Natural Join as a Refined Cross Product
Hook: The Cartesian product pairs everything with everything, and almost all of it is wrong. What if we could keep only the pairs where a common value matches — and throw away the repeated column at the same time? That single idea is the most used operator in all of relational algebra: the natural join.
The natural join is the meaningful version of the cross product. The professor's verbal recipe: "There is a common attribute, let's say A. I am doing select on R1.A is equal to R2.A on R1 cross R2. Then I am projecting all of the attributes of R1 and all of the attributes of R2 — but the common attribute A only once." Reconstructed:
So: take the cross product, keep only the rows where the common attribute matches, and project the common attribute only once while keeping everything else. Whatever is common is matched between the two relations, the values must be equal, and the common attribute appears exactly once in the output. This is the meaningful way to join two different relations without creating spurious tuples or new extra entries.
Formalize the natural join. The recipe decomposes the join into the three operators we already know:
- Cross product — every combination of rows, the raw material.
- Select — keep only the combined rows where the shared attribute has the same value in both halves. This is the matching step; it is why the result contains no spurious combinations.
- Project — keep all attributes of and all attributes of except that one copy of , because the matched value would otherwise appear twice.
The join works on one common attribute, and generally that attribute's name is the same on both sides, so the matching is clear. If the names differ, a rename first makes them match — exactly what the rename operator is for. Because a tuple that has no partner on the other side produces no matching row, the natural join result can be smaller than both inputs; unmatched rows simply do not appear.
7.7.2 Worked Example: Students with CGPA above 9
The setup: the student relation has ID number and name; the CGPA relation has ID number and grade. We want the names of the students whose CGPA is more than 9. If we have only the cross product to work with, we build the answer step by step.
Worked example — the CGPA chain, step by step.
Data: Student holds (1234, Anand) and (5678, Bhavna). CGPA holds (1234, 9.5), (5678, 8.2), and (7895, 9.5) — the last row has a grade but no student carries ID 7895.
Step 1 — the cross product of student and CGPA. The result has four attributes: Student.ID number, Student.name, CGPA.ID number, and CGPA.grade:
With 2 students and 3 CGPA rows, result_1 has rows.
Step 2 — keep only the rows in which Student.ID equals CGPA.ID:
The matching rows are (1234, Anand, 1234, 9.5) and (5678, Bhavna, 5678, 8.2). The row (7895, 9.5) pairs with no student and disappears; so do the cross pairs like (1234, Anand, 5678, 8.2).
Step 3 — keep only the rows in which the grade is greater than 9.0:
Of the two matching rows, only (1234, Anand, 1234, 9.5) passes; Bhavna's 8.2 is below the bar.
Step 4 — project the student name:
The final answer is the single name: Anand. Sense-check: Anand is the only student with a CGPA row above 9.0 — the matching step removed the orphan 7895 row, the grade step removed Bhavna, and the projection left only the name.
The matching behavior: if the CGPA relation has an entry for ID 1234 with CGPA 9.5 and the student relation has ID 1234 for Anand, then only Anand's name results, as the person with more than 9 CGPA. If a CGPA row exists for ID 7895 with CGPA 9.5 but no student carries that ID, the row is excluded — it does not become part of the output. The cross product creates many extra tuples, and that is exactly why the natural join exists: it was designed for this matching purpose. We did one extra step — the special step — of matching the common attribute.
The natural join collapses the chain. The same answer falls out of a single expression once the join exists:
The join matches on the common ID, keeps the ID once, and produces the pairs (1234, Anand, 9.5) and (5678, Bhavna, 8.2) — no orphan row, no cross pairs. The select then keeps the 9.5 row and the project leaves the name. The four-step chain and this single expression compute the same relation; the join is simply the packaged version of "product, then match".
7.7.3 Natural Join on the Company Schema
On the company schema, take the department relation and the employee relation, and join on department number. The common attribute is department number — only one common attribute. The final output takes all the attributes of the department side and all the attributes of the employee side, minus one attribute, because the department number appears only once. How many actual tuples result depends on how many times each department number appears on one side paired with the corresponding tuples on the other side: a department with four employees contributes four joined rows, a department with no employees contributes none.
A natural join works naturally when there is one common attribute, and generally that attribute's name is also the same on both sides, so that the joining is clear. We will not involve inner join or outer join here — those terms belong to the SQL side, so we wait for SQL to come in rather than mixing the words.
7.7.4 Student Questions and Answers
Q: What if there is more than one attribute which is common? How will the join work then? A: I am not sure about it. Generally I have only seen the join working on one common attribute — the natural join works when there is naturally one common attribute, and generally the name also is the same one, to make sure the joining is clear and very clear.
Q: What about inner join and outer join — are they part of this? A: Not here. Those terms are on the SQL side, so just wait for SQL to come in. If you do not understand what people mean by inner join or other terms, simply understand: there is a cross product, from the cross product we take the common attributes, match whether the values of the common attribute are the same or not, project the common attribute only once, and project everything else. That is basically a natural join.
7.7.5 The Manager Question
Here is a very important and exciting question: retrieve the name of the manager of each department. The department relation carries the manager's social security number in the attribute Mgr_ssn (the company-schema convention: Mgr_ssn is a foreign key on the department side that references the Ssn of the employee who manages it). We want the name that belongs to that SSN.
Worked example — manager of each department.
The name lives in the employee relation, keyed by Ssn; the department relation has only the manager's number, Mgr_ssn. The plan has three moves:
- Rename the manager number so it can match the employee key: — or, written cleanly, rename Mgr_ssn to Ssn. The two attributes now share a name and a domain, so the natural join can do its matching.
- Join the renamed department relation with employee on the common attribute Ssn: — each department row combines with the employee row whose number equals the manager number. Every department that has a manager in the employee table contributes one joined row; no spurious combinations are created because only equal values match.
- Project the names: .
The result lists, for every department, the first, middle, and last name of its manager. Sense-check: the join pairs each department with exactly the employee holding its manager number, and the projection keeps only the three name columns — no numbers, no department rows without a manager.
Try it for yourself; we will discuss it next time.
Two more questions from the practice sheet show where the topic is heading. "Retrieve all the supervisors" — if you try it, you will get something very exciting and interesting: there is a limit to relational algebra as well, which the rename-and-join machinery reveals. A supervisor's supervisor is found by joining the employee relation with itself (the self-join that rename enables); but "all supervisors at every level, up and up" would need an unknown number of self-joins — one per level — and no single expression of fixed length can express an arbitrary number of levels. That is a genuine limit of the basic relational algebra. And "retrieve the name of all the employees who work in the research department" — that one needs a join between employee and department on the department number, then a selection on the department name. All of these you can do comfortably and very nicely in relational algebra.
Scope of the natural join. The natural join matches on common attribute names; if the same fact is stored under two different names, rename first or the join will silently not happen. Unmatched tuples are dropped — a department without employees or an employee without a department simply vanishes from the result (preserving them is the job of the outer joins, which belong to SQL). And the "all levels" family of queries — every supervisor, every manager's chain upward — cannot be written as one fixed expression; that needs recursion, which the course meets later.
Recap: Natural join is the meaningful combination operator: cross product, match the common attribute, drop the duplicate column — one expression instead of a chain. It answers the question a student asked in the select section — "what if the attribute is not in this relation?" — by bringing the second table in. This is roughly the last of the core symbols; next session adds aggregation and the remaining joins, and the practice sheet shows how the whole toolkit combines.
Real-world: joins are the workhorse of every business query — order lines joined to orders, bookings joined to flights, transactions joined to accounts. Every such SQL join is a natural join (or a renamed variant of it), and a database that joins well-indexed tables in milliseconds is doing precisely the match-on-common-value idea above, executed by an optimizer that first reorders the joins to keep intermediate results small.
7.8 The Practice Sheet, MySQL Workbench, and Next Steps
7.8.1 The Practice Sheet and Homework
A practice sheet (RA PDF) sits in the files folder under supplementary reading. You can attempt these questions very comfortably in relational algebra: select the employee tuples whose department number is 4; select employee tuples with salary greater than a given value; retrieve the first, middle, and last name; retrieve the social security number; retrieve the name of the manager of each department (the very important question); retrieve all the supervisors; and retrieve the name of all the employees who work in the research department.
The best part: all the solutions are already there in the shared handout, and the handout is already uploaded. A clever person who wants shortcuts can read the handout, do the questions, and then go back to the practice sheet and actually answer it. Attempt the sheet even if you are not 100% correct — the idea is not to be correct; the idea is to be doing something, practicing, and being there, with a commitment that you want to practice. That is more than enough.
Exam note: about 80% of the relational algebra topic is now complete. The aggregation operation (minimum, maximum) and some joins are still pending; they will be covered next session, which also gives the chance to revise whatever we have done till now, take some questions, and then move on. By spreading the topic across two weeks we revise twice, and hopefully you will be able to perform better in the final exams. If we had stretched it over two or three weeks, we would lose momentum; this split keeps the balance.
Exam note: the homework can be shared on WhatsApp or over email, and the instructor is happy to become your accountable partner — so that it is known that you actually did the work. Submitting an attempt — even a partial one — counts far more than waiting for the perfect answer.
7.8.2 Student Questions and Answers
Q: Will you share a common requirement specification for the assignment? If we each do our own thinking, it is difficult for you to evaluate. A: You are absolutely right, 100% right. The requirement specification will be shared very soon, and on that common requirement you can submit the assignment. The submission dates are still there, so there is time.
Q: Can we have something like the inverse of intersection — elements which are not there in both sets? Difference is A minus B, but what about the part in neither? A: Good question — in the Venn diagram, you want the two side regions, not the middle. There is no direct operator for it, but you can do it with what we have: take A union B, and then do the set difference A intersection B from it — . That is one of the ways to get this and this. In the real world I am not sure if that is needed, but it is expressible. This combined expression — the symmetric difference, as it is called in set theory — shows how the six operators compose into a new behavior without inventing a seventh symbol.
Q: Is the workbench free to download, with no license needed? A: Yes — it is completely open source, and no fees are required for individual use. It is freely available even after the course, so you should be able to access it on your own system without worrying about internet connection or other things.
Q: What about students who use an office laptop or a mobile and cannot install new software — is there a possibility of a server or a VMware where we can have access? A: It is a perfectly valid point, and organizations should protect themselves: if any third-party software is installed and deployed on office machines, there can be backdoor entries created and the entire organization can be at jeopardy. So I will discuss with the IT team and ensure that at least this software is installed in the labs. Meanwhile, a stop-gap: pair up with a classmate, use the WhatsApp group, share a Google Meet link, and practice together for an hour — anyone who wants to join can hop in.
7.8.3 MySQL Workbench: Setup and First Commands
To practice SQL hands-on, install two things: the MySQL Community Server and MySQL Workbench. Go to your browser, open mysql.com, go to downloads, and download the community server and the workbench. The workbench is the place where we type in the queries; the server is what connects to the database — you need a server to connect to and a workbench to work with, both installed. If you are on a Mac, go to System Settings, find MySQL, and start the server from there.
Once the server is running, open Workbench. There is a query tab — the place where you write the queries, the place where you get the answer for your queries, and the place where you see whether the query is successful or there is an error. The first command lists the databases currently in your system:
SHOW DATABASES;
Select the text and press the run button. To use an existing database, for example the Sakila sample database, write:
USE sakila;
Then you can ask for the tables in this particular database. Lab sheet 0 talks about exactly this: the query space, the query result space, and how to get started. Don't worry if you do not understand anything at all — it will be revised. The plan for the next session is to practice with the lab sheets, starting from lab sheet 0, then lab sheets 1, 2, 3, as far as you want to go. Before the next session, have SQL Workbench installed on your system so that when the instructor practices, you can practice side by side.
How the pieces connect. The relational algebra of this lecture is the mathematics; MySQL is the machine that executes it. Every SQL query you type — SELECT, WHERE, FROM with two tables — is an expression that the server translates into the operators of this session, and USE sakila; is simply choosing which schema (which set of relations) your expressions will run against. The query tab, result grid, and status area are the workbench's way of showing you the input expression, the output relation, and the success or failure of the run.
7.8.4 Student Questions: Workbench and Lab Access
Q: Why can't we just use the college-provided virtual lab access for everyone? A: The software is freely available, so installing it on your own system gives you access even after the course, with no dependence on internet connection. For office machines, the organization restricts third-party software because of security — backdoor entry risk. The labs will get the software installed, and I will follow up on that before the next week.
Recap: The session ends where practice begins: a practice sheet whose solutions are in the handout, homework you can share with an accountable partner, and MySQL Workbench installed and ready for the lab sheets. The relational algebra toolkit — select, project, rename, union, intersection, set difference, Cartesian product, and natural join — is the complete core; the next session finishes the 20% (aggregation and the remaining joins) and revises.
Real-world: MySQL Community Server and MySQL Workbench are the same open-source stack that powers millions of small and mid-sized web applications — every SHOW DATABASES; and USE sakila; you run on your laptop executes on the same engine family that serves production traffic, so the skills from this lab sheet carry straight into real systems after the course.
7.9 Domain Relational Calculus (DRC)
7.9.1 From Procedural to Declarative
Relational algebra is procedural: a query says step by step how to compute the answer — select these rows, project those columns, join these two tables. The relational calculus is the declarative alternative: a query says what the answer is, and the system figures out how to compute it. SQL, the practical query language, is closer in spirit to the calculus than to the algebra, and the syllabus specifically names the domain calculus variant, so this supplement develops it fully.
Hook: Two restaurants, one recipe. The algebra hands the kitchen a step-by-step instruction list — "take the chicken, boil it, chop it". The calculus hands over the dish description — "chicken soup" — and lets the kitchen decide the order. Both produce the same soup; the calculus just refuses to micromanage. That is the whole difference between the two formal languages of this chapter.
There are two dialects of relational calculus. The tuple relational calculus (TRC) uses variables that range over whole tuples — a variable stands for a complete row of a relation. The domain relational calculus (DRC) uses variables that range over domains — individual attribute values — so a row is described by a collection of single-value variables, one per attribute. Historically, DRC underlies the QBE (Query-By-Example) language developed at IBM Research: a user sketches a table with example values, and the system translates the sketch into a domain calculus expression.
| Aspect | Relational algebra | Tuple calculus (TRC) | Domain calculus (DRC) |
|---|---|---|---|
| Style | Procedural | Declarative | Declarative |
| Variable stands for | — (operations on relations) | A whole tuple | One domain value |
| Query shape | Nested operator expression | ||
| Closest SQL relative | Execution plan | Alias + join reasoning | SELECT ... FROM ... WHERE ... |
7.9.2 The Shape of a DRC Query
A DRC query is written as a set comprehension:
The answer is the set of all combinations of domain values that make the predicate true. The predicate is built from two kinds of atoms, combined with (and), (or), (not), and the two quantifiers:
- Membership atom: — the values form a tuple of relation . This is the DRC way of saying "there is a row of with these values."
- Comparison atom: or , where is , and are domain variables, and is a constant — e.g.,
salary > 30000.
Free variables are the answer list. In the expression above, the variables written to the left of the bar are the free variables of the query — the ones the answer returns. Every other variable in the predicate must be bound by a quantifier; if a variable appears in the predicate but is neither in the answer list nor bound by a quantifier, the query is ill-formed. Think of the free variables as the columns of the output table: a one-variable answer list produces a one-attribute relation, an -variable list produces a relation of degree .
To work the examples, fix a small schema in the style of the course: and .
7.9.3 Quantifiers: Existential and Universal
The existential quantifier ("there exists") and the universal quantifier ("for all") bind variables in a predicate, and a variable that is not bound by any quantifier is a free variable — the free variables are exactly the ones that appear in the answer list . For readability, a quantified variable that ranges over a relation is often written in the quantified form .
- : the formula is TRUE if at least one assignment of values to the bound variables makes it TRUE. This is the DRC spelling of "some row exists that ...".
- : the formula is TRUE if every possible assignment makes it TRUE. This is the DRC spelling of "for all rows, ...".
A universal claim about the interesting rows is almost always written as an implication: "for all rows : if is in department 5, then 's salary is larger". In logic, the implication is equivalent to — so the DRC form becomes . The trick matters: the universal quantifier ranges over everything, so every row that is not in the group we care about must be made harmless by making the clause true for it automatically.
7.9.4 Worked Examples
Example 1 — Selection and projection (free variables + ). Find the names of employees earning more than 30,000:
The predicate says: there exists an EMP row whose salary component satisfies salary > 30000, and the answer returns only the ename component. Notice the structure — the membership atom declares the variables, the comparison atom filters them — this is the DRC translation of SELECT ename FROM emp WHERE salary > 30000.
Work it on two rows: (11, Anand, 50000, 5) and (12, Bhavna, 25000, 5). For Anand, the membership atom finds the row and 50000 > 30000 is TRUE, so Anand's name enters the answer. For Bhavna, 25000 > 30000 is FALSE, so her name does not. Answer: Anand. Sense-check: the free variable list has one member, so the result is one-attribute relation; the comparison does the same work a select would do in the algebra.
Example 2 — Join (shared variable connects two membership atoms). Find the names of employees who work in the Research department. The join is expressed by reusing the same domain variable in both relations:
The two membership atoms together require a row of EMP and a row of DEPT, and the equality ties them — exactly what the natural join of relational algebra expresses.
Work it with DEPT holding (5, Research) and (4, Administration), and EMP rows (11, Anand, 50000, 5), (13, Charu, 60000, 4). For e = Anand: the DEPT atom supplies (5, Research); and Research = 'Research' both hold, so Anand qualifies. For e = Charu: her dno is 4, which matches (4, Administration), but Administration = 'Research' is FALSE; no other DEPT row exists, so Charu fails. Answer: Anand. Sense-check: the shared variable performs the join condition, and the constant comparison performs the selection on the department name — the DRC expresses in one comprehension what the algebra needs a join plus a select for.
Example 3 — Universal quantifier (the "for all" reading). Find employees whose salary is greater than the salary of every employee in department 5. The trick is to convert "greater than everyone in department 5" into a condition on every EMP row, using the implication form , which in DRC is written with :
For every employee : either is not in department 5, or 's salary beats 's. Because every non-department-5 row makes the predicate true regardless of salary, only the department-5 rows are actually compared — this is the standard, safe way to express "better than all" queries in calculus, and it is exactly the shape SQL compiles NOT EXISTS and ALL into.
Work it with three EMP rows: Anand (50000, dept 5), Bhavna (40000, dept 5), Charu (60000, dept 4). Test candidate = Charu against every : against Anand, , so we check — TRUE; against Bhavna, — TRUE; against herself, , so the clause is TRUE without any salary check. Every passes, so Charu qualifies. Test = Anand: against Bhavna, — TRUE; against himself, — FALSE, so Anand fails. Answer: Charu. Sense-check: Charu earns more than both department-5 employees, while Anand does not beat his own equal salary — the "strictly greater than every member" reading is exactly right.
7.9.5 Safety and Relational Completeness
Two facts to hold onto for the exam: first, every query expressible in relational algebra is expressible in DRC (and vice versa) — Codd's equivalence result — but the safe-expression condition must hold: the answer must be built only from values appearing in the database, never from quantifiers ranging over infinite domains. Second, of the two calculus dialects, SQL's SELECT ... FROM ... WHERE ... is syntactically nearest to the domain calculus — each table alias is a quantified tuple, the WHERE is the predicate, and the SELECT list is the free variables — which is why "relational calculus" is named as examinable material in the course's own syllabus recap.
Unsafe expressions. A formula like asks for every value that is not an employee number — an infinite set, since the domain of possible values is unbounded. Such an expression is unsafe: it cannot be computed. Safety means every value in the answer must come from the database itself — from the constants in the query or from tuples of the relations mentioned. Every example in this section is safe; every textbook rule for using (make the non-target rows automatically TRUE) exists precisely to keep expressions safe.
Recap: The domain relational calculus replaces the algebra's step-by-step recipe with a declarative description: a set comprehension whose free variables are the answer columns and whose predicate is built from membership atoms, comparison atoms, and the quantifiers and . Algebra and calculus are equal in power — Codd's equivalence — and SQL is the DRC's closest practical cousin. Where the algebra is the language of the optimizer, the calculus is the language of the question.
Real-world: every ORM (object-relational mapper) and every AI query generator works in the calculus mindset — it describes what data is wanted and lets the engine decide how. The WHERE clauses, IN (SELECT ...) subqueries, and NOT EXISTS conditions that appear in production SQL are all, under the hood, membership atoms, comparison atoms, and quantifiers of exactly the kinds written above.
7.10 Heuristic Query Optimization
The lecture closed with the promise that query optimization is taught theoretically, through relational algebra. This supplement supplies that theory: given one SQL query, a DBMS can generate many equivalent relational algebra expressions, and optimization is the science of picking the cheapest one. The syllabus names two ingredients — equivalence rules and cost models — and the heuristic strategy uses the first without needing the second in detail.
Hook: The same question can be answered by a dozen different relational algebra expressions — some finishing in milliseconds, others taking minutes. Which one does the database run? The answer is the topic of this section: the DBMS rewrites the query with equivalence rules, prices the alternatives with a cost model, and executes the cheapest.
7.10.1 Equivalence Rules for Relational Algebra
Two expressions are equivalent when they always produce the same result on every database instance. The equivalence rules are the rewrite toolkit of the optimizer. The core rules (standard, from every database textbook):
- Cascading selections: — a conjunctive selection can be split into a sequence of selections, and the order of two consecutive selections may be swapped: .
- Cascading projections: when — projecting away attributes twice is the same as projecting once to the smaller list.
- Commutativity and associativity of joins and products: ; — the optimizer may join relations in any order, which is the freedom the join-ordering heuristics exploit. The same holds for the Cartesian product.
- Selection with product becomes join: — a Cartesian product immediately followed by a selection is a theta join, and joins are far cheaper than products.
- Selection distributes over joins and products: when the selection condition mentions only attributes of — filtering one side before the join shrinks the input. The same rule applies to the product.
- Selection and projection distribute over union: , — and selection also distributes over intersection and set difference.
Why equivalence rules can be used fearlessly. The symbol is a guarantee, not a guess: the two sides produce the same set of tuples on every legal database instance, no matter what data the tables hold. So the optimizer is free to rewrite any subexpression from one side of a rule to the other — the answer cannot change. What does change is the cost: rules 4 and 5 shrink the data flowing through the tree, which is why they sit at the heart of every optimizer. Notice that these rules echo the properties already met in the lecture — select and project compose (7.2, 7.3), joins are commutative and associative (7.7) — the algebra was built for this rewriting.
7.10.2 The Heuristic Strategy
A heuristic optimizer does not enumerate every plan and price it — it applies a fixed set of common-sense rewrite rules that almost always reduce cost. The canonical strategy, in order:
- Push selections down as far as possible (rule 5, applied repeatedly). A selection shrinks the number of tuples flowing up the operator tree, and everything above the selection does less work. This single rule is the biggest win in practice.
- Push projections down as far as possible (rule 2, applied to keep only needed attributes). A projection shrinks tuple width, so more tuples fit in a block and in memory.
- Combine a Cartesian product with a following selection into a join (rule 4) — and never execute a bare product followed by a separate selection when they can merge.
- Reorder joins to join the smallest relations first — since joins associate and commute (rule 3), the optimizer joins the relation expected to produce the fewest tuples earliest.
- Cascade selections, then commute and reorder the remaining operators using the rules until the tree is in canonical form.
Worked mini-example — pushing selections down changes the workload.
The query "names of employees earning over 30,000 who work in the Research department" compiles to the tree .
Naive plan: join the full EMP and DEPT tables (say 100,000 employee rows and 1,000 department rows), then filter the combined result — every one of the ~100,000 joined rows must be built, scanned, and tested, and only a handful survive.
Optimized plan — apply the rules in order:
- Rule 1 (cascade): split the combined condition: .
- Rule 5 (push selections): mentions only DEPT attributes, so push it into DEPT before the join; mentions only EMP attributes, so push it into EMP before the join:
- Rule 2 (push projection): the only attribute needed from the join is ename (plus the join attributes), so project — and the join columns — below the join.
The join now processes only the research department's few tuples and the few high-salary employees instead of every row of both tables — the same answer, a fraction of the work. Payoff: the rewrite never changes the result, but it can turn a query that joins two full tables into one that joins two small selections — often orders of magnitude faster.
7.10.3 Cost Models: Block Accesses and CPU
The heuristic rules improve almost any query, but the decision rules of a real optimizer need a numeric yardstick: a cost model. The standard model counts the two resources that the storage lectures made central:
Block transfers and seeks dominate everything — the access-time discussion of the storage session showed seek plus rotational latency is an order of magnitude above transfer time, so seeks are weighted correspondingly heavily. Each plan is priced by estimating the size of the intermediate results at every step, using the statistics a DBMS keeps (number of tuples per relation, number of distinct values per attribute, and the selectivity factor of each condition — the fraction of tuples a predicate is expected to pass).
Worked numerical — pricing two plans in the cost-model units.
A relation holds 300,000 records, stored 40 records per block. Plan A is a full scan: it must read every block, so it costs block transfers. Plan B uses a primary index on the key: the index (a B+-tree) needs about 4 block accesses — 3 index levels plus the data block — to reach the one record wanted. Priced with the formula:
Plan B wins by roughly a factor of 1,800 on block transfers alone — and since a seek typically costs far more than a transfer, the real gap is even wider. Sense-check: the scan cost is the record count divided by the blocking factor — exactly the arithmetic of the storage lectures — and the index path is the tree height plus one, which matches the 4-access figure cited there.
The worked numerical from the indexing session is exactly this arithmetic: a full scan of 300,000 records in blocks of 40 records costs 7,500 block transfers, while the primary index cuts the lookup to 4 block accesses — the optimizer would be choosing between plans priced in precisely these units. Course-level exam questions expect this qualitative-and-numerical level: enumerate the plans, count block accesses for each, pick the cheapest, and justify with the rules.
Real-world: real optimizers (MySQL's, PostgreSQL's, Oracle's) do exactly this — they translate SQL to a relational algebra tree, rewrite it with equivalence rules, estimate the cost of each candidate plan from statistics, and execute the cheapest. The course's theoretical treatment is the same science; the practical tuning, as the lecture noted, needs administrative privileges on a real system.
Recap: Optimization is rewriting without changing the answer: equivalence rules say what may be rewritten, the heuristic strategy says what to rewrite first — push selections and projections down, merge product with selection into a join, join smallest first — and the cost model says how to compare the alternatives. This is where the whole lecture's algebra finds its payoff: every operator learned in 7.2–7.7 is a node in the trees an optimizer reorders every day.
Exam Guidance Summary
- Coverage so far: roughly 80% of relational algebra is complete. The aggregation operation (minimum, maximum) and some joins are still pending and will be covered next session, together with a revision. Spreading the topic over two weeks means you revise twice — the stated goal is better performance in the final exams.
- Correctness over efficiency: in relational algebra answers, every correct option is accepted; query optimization and efficiency is a separate topic. When the attribute survives the projection, select-then-project and project-then-select both fetch full marks.
- Relations are duplicate-free: the final result of any operation — select, project, union, intersection, set difference, Cartesian product, join — is a relation, so expect duplicate-elimination questions (union of overlapping sets, projection of non-key attributes, distinct supervisors).
- Important question: "retrieve the name of the manager of each department" (rename the manager SSN, join, project names) was flagged as very important. "Retrieve all the supervisors" exposes a limit of relational algebra.
- Reading the requirement: the department number lives in four relations (department locations, department, project, employee); the user's phrasing decides which relation you operate on.
- Homework: the RA practice sheet in the files folder; solutions are in the shared handout. Attempt the questions even if not fully correct; share attempts on WhatsApp or email. The instructor acts as an accountable partner.
- Assignment: a common requirement specification will be shared so submissions can be evaluated fairly.
- Tooling: install MySQL Community Server and MySQL Workbench before the next session; lab sheet 0 covers the query space, result space, and status area.
Exam note: the questions to rehearse before the next session are the practice sheet's own: select on department 4, salary above a bound, the three-name projection, and the three joins — manager of each department, all supervisors, and employees of the research department. Know the three size facts cold — attributes add and tuples multiply in the product, the join keeps the common attribute once — and remember that every answer is judged on correctness first, efficiency later.
Key Industry Applications
- Every application category — supply chain, railways, airlines, banking, agriculture, automobile, edtech — runs on data; storing and retrieving data well, with concurrent access for many users, is what lets an application scale. A prototype-stage startup can live on an ER diagram and a basic relational schema, but a commercial application needs a normalized schema (semantics, minimal redundancy, minimal nulls, minimal spurious tuples).
- Real-world: SQL query optimization is done in relational algebra terms — the DBMS's query optimizer thinks in exactly this mathematics.
- Real-world: MySQL Workbench and MySQL Community Server are free, open-source tools you keep after the course; SHOW DATABASES, USE, and the query/result/status areas are the everyday work surface for practicing SQL from the lab sheets.
- Real-world: organizations block third-party software installs on office machines because of backdoor/security risk; software is provisioned through labs instead.
- Real-world: the relational algebra ↔ SQL correlation is useful beyond programming — the same retrieval logic shows up in management and sales thinking.
The one-sentence industry takeaway: every report, dashboard, and search bar in the applications listed above is a relational algebra expression in disguise — a select to filter rows, a project to narrow columns, a join to combine tables — and the same three moves are what a query optimizer reshuffles to keep those applications fast at scale.
DDA Lecture 7 notes · Relational Algebra: Select, Project, and Joins
Sections Breakdown
Data at the heart of every application; why retrieval needs the unambiguous mathematics of relational algebra.
The row filter: predicates, comparison operators, and worked examples on the company schema.
The column filter: attribute lists, duplicate elimination, and composing select with project.
Renaming relations and attributes position by position, and naming intermediate results for self-joins.
Union-compatible relations and the duplicate-free combination of relation sets, with worked examples.
Attributes add and tuples multiply; why the bare product is usually meaningless.
Cross product, match the common attribute, keep it once: the meaningful join, from the CGPA chain to the manager question.
The practice sheet, homework, and setting up MySQL Workbench for the lab sheets.
Declarative queries: set comprehensions, free and bound variables, quantifiers, safety, and Codd's equivalence.
Equivalence rules, pushing selections and projections down, and cost models in block transfers and seeks.
The exam strategy for relational algebra: coverage, correctness first, duplicate-free relations, and the practice-sheet questions.
How select-project-join retrieval, optimizers, and MySQL power real applications.
Exam Revision Notes
Below is the distilled, exam-ready core. Every entry comes from the full explanation above. Use this section for rapid review; return to the main notes when a point needs more context.
Why Relational Algebra Exists
Must-know: Relational algebra is the mathematical, unambiguous, deterministic basis of retrieval and of SQL query optimization; select-the-word has different meanings in algebra (rows) and SQL (columns).
⚠️ Top pitfall: Mixing the meanings of 'select' between relational algebra (row filter) and SQL (column chooser).
Self-check: Why is mathematics preferred over spoken language for specifying what to retrieve?
Connects to: Select (7.2), Project (7.3)
Select
Must-know: Select keeps rows satisfying a predicate, never removes columns; a missing attribute means you must bring in another relation via cross product or join.
⚠️ Top pitfall: Thinking of the SQL SELECT clause while doing relational algebra — in algebra, select only filters rows; the word means something different in SQL.
Self-check: What does sigma_{Dno = 4}(Employee) return, and which attributes does the result have?
Connects to: Project (7.3), Cartesian Product (7.6), Natural Join (7.7)
Project
Must-know: Project keeps listed attributes only and removes duplicate tuples; if the projection drops the attribute a later select filters on, that filter silently does nothing.
⚠️ Top pitfall: Projecting first and then selecting on an attribute that was removed — the select becomes a no-op with no error and no nulls.
Self-check: When does a projection keep the tuple count unchanged? (When the attribute list is a superkey.)
Connects to: Select (7.2), Rename (7.4), Heuristic Query Optimization (7.10)
Rename
Must-know: Rename rho_S(B1,...,Bn)(R) renames relation and attributes position-by-position; renaming is what lets one relation be used twice and lets join attributes match by name.
⚠️ Top pitfall: Listing new attribute names in a different order than the relation's actual attributes — the rename is positional.
Self-check: Why is rename necessary before a natural join when the join attributes have different names in the two relations?
Connects to: Union, Intersection, and Set Difference (7.5), Natural Join (7.7), Project (7.3)
Union, Intersection, and Set Difference
Must-know: Set operations require union-compatible relations; the result of any operation is a duplicate-free relation; set difference is not commutative.
⚠️ Top pitfall: Using one projection of both attributes instead of two projections joined by union — pairs are not the 'either-or' set the requirement asks for.
Self-check: Student contains Susanne and Ramesh, instructor also contains them. What does student set difference instructor return?
Connects to: Rename (7.4), Cartesian Product (7.6), Project (7.3)
Cartesian Product
Must-know: R x S has the sum of attributes and the product of tuple counts; the product alone is meaningless, product-then-selection is a join.
⚠️ Top pitfall: Saying the product carries over tuple counts instead of multiplying them — three by four is twelve, not seven.
Self-check: A 3-tuple relation crossed with a 4-tuple relation: how many tuples result?
Connects to: Natural Join (7.7), Union, Intersection, and Set Difference (7.5), Heuristic Query Optimization (7.10)
Natural Join
Must-know: Natural join = select on the equal common attribute over the cross product, projecting the common attribute once; manager-of-each-department is rename Mgr_ssn to Ssn, join with employee, project names.
⚠️ Top pitfall: Joining without renaming when the shared fact has different attribute names — the join silently matches nothing; and forgetting that unmatched tuples are dropped.
Self-check: Why is the row for CGPA ID 7895 missing from the 'CGPA above 9' answer?
Connects to: Cartesian Product (7.6), Rename (7.4), Union, Intersection, and Set Difference (7.5), Select (7.2)
The Practice Sheet, MySQL Workbench, and Next Steps
Must-know: 80% of relational algebra is done; aggregation (min/max) and some joins are pending next session; practice sheet solutions are in the handout; MySQL Workbench setup precedes the lab sheets.
⚠️ Top pitfall: Waiting for a perfect submission instead of attempting the sheet — the point is committed practice, not instant correctness.
Self-check: How is the symmetric difference — elements in neither intersection's middle — expressed with the operators we have?
Connects to: Union, Intersection, and Set Difference (7.5), Natural Join (7.7)
Domain Relational Calculus (DRC)
Must-know: DRC queries are set comprehensions {<x1..xn> | P} where the free variables are the answer; algebra and calculus have equal expressive power (Codd), but expressions must be safe — answers built only from database values.
\{\langle x_1, x_2, \ldots, x_n \rangle \mid P(x_1, x_2, \ldots, x_n)\}
⚠️ Top pitfall: Writing an unsafe expression whose result would be infinite (e.g., negation without a membership atom), or leaving a predicate variable neither free nor quantified.
Self-check: Why is 'salary greater than every employee in department 5' written with x.dno ne 5 OR e.salary > x.salary?
Connects to: Heuristic Query Optimization (7.10), Natural Join (7.7), Select (7.2)
Heuristic Query Optimization
Must-know: Equivalent expressions always produce the same tuples on every instance; heuristics push selections and projections down, merge product+selection into a join, and join smallest relations first; cost = transfers * cB + seeks * cS + CPU.
⚠️ Top pitfall: Executing a bare Cartesian product or filtering after the join instead of pushing the selection into the inputs — the same answer at many times the cost.
Self-check: Why is sigma_c(E1 join E2) equivalent to sigma_c(E1) join E2 when c mentions only E1 attributes?
Connects to: Natural Join (7.7), Select (7.2), Project (7.3), Cartesian Product (7.6)
Exam Guidance Summary
Must-know: The practice-sheet questions are the revision list; attributes add and tuples multiply; every result is a relation with no duplicates; the manager-of-each-department question is the flagged important one.
⚠️ Top pitfall: Answering before reading which relation the user's phrasing points to.
Self-check: Which four relations hold the department number, and how does the user's phrasing decide the one to use?
Connects to: Select (7.2), Project (7.3), Union, Intersection, and Set Difference (7.5), Natural Join (7.7), The Practice Sheet, MySQL Workbench, and Next Steps (7.8)
Key Industry Applications
Must-know: Select, project, and join are the three moves behind every report and dashboard; query optimizers reshuffle exactly these operators to keep applications fast.
Self-check: Why must a commercial application use a normalized schema while a prototype can start from an ER diagram?
Connects to: Why Relational Algebra Exists (7.1), The Practice Sheet, MySQL Workbench, and Next Steps (7.8), Heuristic Query Optimization (7.10)
Was this lecture useful?
BitsNotes AI Assistant
Subject Notes AssistantConfigure AI Chat
Choose how to access the chatbotSigned in as
Powered by BitsNotes — 20 messages per day. No API key needed. Want unlimited access? Use "Bring Your Own Key" mode.
Sign in to use AI Chat
Get 20 free AI messages per day to ask questions about your lecture notes. Sign in with Google or GitHub — it takes 5 seconds.
Sign In to BitsNotesSwitch to "Bring Your Own Key" tab above for unlimited access with any OpenAI-compatible provider.