Relational Algebra - exercises
Suppose a hospital database with following structure:
**PATient** (__PatientID__, PatientNAme, PaADdress, PatientDofBirth)
**DOCtor** __(DoctorID__, DoctorNAme, SPEcialization)
**VISit** (__PatientID, DoctorID, DateofVIsit__, DIAgnose)
Let us short the names of relations and attribute as follows:
**PAT** (__PID__, PNA, PAD, PDB)
**DOC** (__DID__, DNA, SPE)
**VIS** (__PID, DID, DVI__, DIA)
Write following queries in realtional algebra:
1. List of all doctor's specializations
DOC[SPE]
//The duplicities are filtered automatically//
2. Names of all orthopeds.
DOC(SPE='ORTOPED')[DNA]
But two orthopeds with the same name are treated as one in above solution, hence we can do:
DOC(SPE='ORTOPED')[DNA, DID]
3. Names and addresses of all patients borned before 1920 (suppose date attributes in format YYYYMMDD).
PAT(PDB < '19200101')[PNA, PAD]
//Texts and data atributes are enclosed in apostrophes.//
4. DID's of doctors visited by patient Scott.
PAT(PNA='SCOTT')[PID]*VIS[DID]
or
PAT*VIS(PNA='SCOTT')[DID]
//Formulations are equivalent. The later is more readable.//
5. Names of internist visited by patient Scott.
PAT*VIS*DOC(SPE='INTERNISTA' AND PNA='SCOTT')[DNA]
6. Names and addresses of patients visited by doctor Jones.
PAT*VIS*DOC(DNA='JONES')[PNA, PAD]
7. Names and address of patients visited only by doctor Jones (i.e. by no other doctor).
PAT*VIS*DOC(DNA='JONES')[PNA, PAD]
- (set minus)
PAT*VIS*DOC(DNA<>'JONES')[PNA, PAD]
8. Two-tuples of names of patients living in the same address.
P1 := PAT
P2 := PAT
P1 x P2 (P1.PAD = P2.PAD AND P1.PID < P2.PID)[P1.PNA, P2.PNA]
alternatively:
P1 [P1.PAD = P2.PAD AND P1.PID < P2.PID] P2 [P1.PNA, P2.PNA]
9. The doctors who already had patients.
DOC <* VIS
10. Names of doctors who have no patients yet.
DOC “antijoin” VIS
alternatively:
DOC - (DOC<*VIS)
11. Which specialization did not work yet.
**Carifull, this is wrong: !!!**
DOC “antijoin” (VIS [SPE])
//There may be more doctors with the same spec.//
**And this is correct:**
DOC[SPE] - (DOC*VIS[SPE])
12. Names and addresses of patients with diagnose diabetes (do not use a natural join for this query).
(PAT x VIS (DIA = 'DIABETES' AND PAT.PID = VIS.PID))[PNA, PAD]
alternatively:
(PAT [DIA='DIABETES' AND PAT.PID = VIS.PID] VIS )[PNA, PAD]
13. The patients who visited any doctor.
// = the patients who were on the visit//
PAT<*VIS
14. The patients who did not visited each doctor. Including the patients without visits.
((PAT[PID] x DOC[DID]) – VIS[PID,DID])[PID]*PAT
15. The patients who visited all doctors.
**Solution without using relational division**
Idea:
All patients who were in a visit
- (set minus)
The patients who did not visit any doctor.
//All patients who were on a visit://
VIS[PID]
//The patients who did not visit any doctor://
the universe
(each patient who were on visit visited each doctor):
U := VIS[PID] x DOC[DID]
reality - which visits realy happend:
R := VIS[PID, DID]
The visits which were not realized:
N:= U – R
The patients who did not visit any doctor
(there is a doctor who was not visited by them)
N[PID]
The result is:
(VIS[PID] – N[PID]) * PAT
**Solution with using relational division**
(VIS[PID, DID] “divided by” DOC[DID]) * PAT
16. The patients who visited at least one othoped.
= the patients who visited any orthoped
PAT<*(VIS*DOC(SPE='ORTOPED'))
17. The patients who did not visited any orthoped.
PAT - (PAT<*(VIS*DOC(SPE='ORTOPED')))
alternatively
PAT “antijoin” (VIS*DOC(SPE='ORTOPED'))
18. The patients from Pardubice who visited each orthoped.
(VIS[PID, DID]
“divided by”
(DOC(SPE='ORTOPED')[DID])))
* PAT (PAD='PARDUBICE')