Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: June 25, 2025
Relational algebra is the mathematical model of the query languages used in relational database systems. Its operations take relations as input and produce relations as output.
In this tutorial, we’ll learn how to find the maximum value in relational algebra.
The basic operations in relational algebra are:
This set of operations is usually extended with join operators () and sometimes with aggregations (
). The latter are equivalent to SQL aggregations, and in such extensions, finding the maximum is trivial, as MAX is a core operation of the algebra. Therefore, we’ll focus on implementing MAX using only the basic operations and joins.
Let’s say we have a relation in which we record how many points contestants scored in a tournament:
| id | points |
|---|---|
| A1 | 67 |
| A2 | 78 |
| A3 | 85 |
| A4 | 85 |
The task is to find the contestant with the most points.
To solve it using relational algebra, we’ll first talk about defining a set’s maximum value.
In mathematics, we differentiate between the maximal and greatest elements of a set.
The greatest element of a set is the one that is greater than all the other elements of that set:
On the other hand, the maximal element is the one that is not less than any other element. Mathematically:
We use the latter definition to implement MAX. We will do it in two steps:
The second step finds those with maximal points because if a contestant isn’t found in the first step, then no other contestant has more points, which is the maximum’s definition.
To find the contestants with fewer points than at least one other contestant, we’ll first compute the Cartesian product of with a renamed version of itself. Then, we’ll filter the product relation.
Let’s do the renaming and compute the product:
This is the resulting relation:
| id1 | id2 | points1 | points2 |
|---|---|---|---|
| A1 | A1 | 67 | 67 |
| A1 | A2 | 67 | 78 |
| A1 | A3 | 67 | 85 |
| A1 | A4 | 67 | 85 |
| A2 | A1 | 78 | 67 |
| A2 | A2 | 78 | 78 |
| A2 | A3 | 78 | 85 |
| A2 | A4 | 78 | 85 |
| A3 | A1 | 85 | 67 |
| A3 | A2 | 85 | 78 |
| A3 | A3 | 85 | 85 |
| A3 | A4 | 85 | 85 |
| A4 | A1 | 85 | 67 |
| A4 | A2 | 85 | 78 |
| A4 | A3 | 85 | 85 |
| A4 | A4 | 85 | 85 |
Now, let’s keep only the tuples in which :
This gives us:
| id1 | id2 | points1 | points2 |
|---|---|---|---|
| A1 | A2 | 67 | 78 |
| A1 | A3 | 67 | 85 |
| A1 | A4 | 67 | 85 |
| A2 | A3 | 78 | 85 |
| A2 | A4 | 78 | 85 |
The first column contains the contestants who “lost” to at least one other contestant, so they can’t have the maximum number of points. Let’s do the projection:
Now, we have those IDs in this unary relation:
| id1 |
|---|
| A1 |
| A2 |
The set difference of and
contains the IDs of the contestants with the maximum number of points. We rename the attribute
of
to
so that the attribute names match:
This is the correct result, as the contestants A3 and A4 have the same number of points, more than A1 and A2. As we see, there can be more than one maximum.
The same logic applies to finding the minimal values. We only have to replace with
.
Filtering the Cartesian product is essentially a join operation:
So, we can streamline those two steps in the computation of maximum values:
If another relation stores the contestants’ info, we can join the relations using the IDs to include those attributes in the result.
If we want to see the maximal points in addition to the IDs, we should keep when applying the projection to
:
To get only the maximal number of points, we project :
What if the tournament is not all vs. all, but contestants compete within groups?
Let’s say the relation is , where
is the contestant’s ID:
| group | id | points |
|---|---|---|
| G1 | A1 | 67 |
| G1 | A2 | 78 |
| G1 | A3 | 85 |
| G2 | B1 | 50 |
| G2 | B2 | 65 |
| G2 | B3 | 65 |
We start the same way as before, by renaming the relations:
However, when joining, we include the condition that in addition to
. It means the comparisons will be performed only within groups:
This returns:
| group1 | id1 | points1 | group2 | id2 | points2 |
|---|---|---|---|---|---|
| G1 | A1 | 67 | G1 | A2 | 78 |
| G1 | A1 | 67 | G1 | A3 | 85 |
| G1 | A2 | 78 | G1 | A3 | 85 |
| G2 | B1 | 50 | G2 | B2 | 65 |
| G2 | B1 | 50 | G2 | B3 | 65 |
Now, we do the projection, keeping the attributes and
in addition to
:
Since relations are sets, all the tuples are unique. So, the duplicates are filtered out automatically:
| group1 | id1 | points1 |
|---|---|---|
| G1 | A1 | 67 |
| G1 | A2 | 78 |
| G2 | B1 | 50 |
We rename the attributes of to match those of
and find the set difference of
and the renamed
:
This way, we get the contestants with maximum points per group:
| group | id | points |
|---|---|---|
| G1 | A3 | 85 |
| G2 | B2 | 65 |
| G2 | B3 | 65 |
In this article, we discussed how to find the maximum in relational algebra. The idea is to find the set of values that are less than at least one other value in the relation. The maximal values are those that aren’t in that set.