Given the schema Students(id:integer,grade:integer)
, you can solve the problem in tuple relational calculus by using the negation operator (¬
).
{T1.id | ∃T1 ∈ Students ¬(∃T2 ∈ Students (T2.grade > T1.grade))}
This would return the id of all students in T1 where there is no student in T2 with a higher grade.
Because T1 and T2 are from the same relation, this effectively returns the set of students with the top grade.
If there are no ties for the top grade, it will return just one id.
It looks like you were thinking in terms of relational algebra rather than tuple relational calculus.
Tuple relational calculus does not have a set difference operator, so you can't find the maximum by subtracting all non-maximums.
Reference
The Solutions Manual for the third edition of Database Management Systems by Ragu Ramakrishnan and Johannes Gerke helped me solve this.
Question 4.3 asks you to solve some problems using this schema:
Suppliers(sid:integer,sname:string,address:string)
Parts(pid:integer,pname:string,color:string)
Catalog(sid:integer,pid:integer,cost:real)
Question 4.3.11 is similar to yours.
Find the pids of the most expensive parts supplied by suppliers named Yosemite Sham.
The solution looks like this:
{T | ∃T1 ∈ Catalog(∃X ∈ Suppliers
(X.sname = 'Yosemite Sham' ∧ X.sid = T1.sid) ∧ ¬(∃S ∈ Suppliers
(S.sname = 'Yosemite Sham' ∧ ∃Z ∈ Catalog
(Z.sid = S.sid ∧ Z.cost > T1.cost))) ∧ T.pid=T1.pid)}
The solution here is more complicated because of the joins between Suppliers and Catalog, but the essence of the solution is the same.
Elide the joins to get this:
T1 ∈ Catalog ...
(... ¬(... ∃Z ∈ Catalog
(... Z.cost > T1.cost)))
In the reference solution, free variable T has the same pid as bound variable T1.
Taking the pid of T1 directly is a simpler way to get the same result.
Your relation is in 3NF, (and not only in 2NF), since as you say the only non prime attribute is Grade, which only appears on the right hand side of your FDs.
The relation is not in BCNF, because the left hand side of the two small FDs is not a superkey.
You can, however, losslessly decompose the relation to
(SubjectCode, SubjectName) and either
(StudentName, SubjectCode, #Exam, Grade)
or
(StudentName, SubjectName, #Exam, Grade)
This decomposition gives you two BCNF relations and preserves all functional dependencies. This isn't always possible (you can always decompose a relation to 3NF, but not necessarily to BCNF).
2NF
If you want an example of 2NF (and not 3NF), your relation needs to contain transitive dependencies.
For instance, say you have a Score column. Intuitively Score->Grade since all exams with the same score should get the same grade (it would be rather unfair otherwise), but note that we cannot say Grade->Score since several scores can have the same grade (11% and 12% would likely be "Fail", for instance).
Now your relation is:
Gradings(StudentName, SubjectCode, SubjectName, #Exam, Score, Grade)
and you have a new form of redundancy since every time you enter a result with the same score as another Gradings record you also have to repeat the corresponding Grade. To get to 3NF you could therefore decompose to
ScoreGrades(Score,Grade)
with Score as the key, and
Scores(StudentName, SubjectCode, SubjectName, #Exam, Score)
Best Answer
I don't actually feel very comfortable with relational algebra, so, I'll do it first using standard SQL and then use a tool called RelaX - relational algebra calculator 0.18.2 to do the translation.
First, the table you wrote, I'll call it students, and define it and fill it with:
RelaX will translate this into a dataset, represented by the following tuples:
In order to find what you're looking for, we first need a table with tuples in the form
(state, grade)
, having the maximum grade of each state. This query is done, in SQL with aMAX(grade)
perstate
using aGROUPs BY state
. You would write it like:Next, you need to
JOIN
this table (that is namedmax_grades
) to thestudents
one, and you do itON
equal states, and equal grade (i.e.: the max grade per state)...... and this gets translated by RelaX to the following relational algebra expression and reponse:
NOTE1:
Alternative:
If you cannot
GROUP BY
, you can use another construct:This goes a bit more in-line with your original thinking, although I personally find it less clear...
The translation to relational algebra is: