-- Relaciona algeba
-- Prosirenje skupovne algebre:
--     unija, presek, razlika, proizvod +
--     projekcija,restrikcija, prirodno spajanje

-- *  RESOURCES: http://poincare.matf.bg.ac.rs/~smalkov/files/urbp.rm13.2020/public/predavanja/Uvod%20u%20relacione%20baze%20podataka%20-%2004%20-%202020%20-%20Relacioni%20model.pdf
--     [FROM SLIDE 10]
-- *  DB: http://poincare.matf.bg.ac.rs/~milan_cugurovic/baze/sources/shema_baze.png
--     [SMALL NAMING MODIFICATION: in the case of the foreign key use 'more general' name (idPredmeta in predmet, idPrograma in dosije, idNivoa in studijskiProgram)
-- * CAN USE TOOL (Developed by Ana Spasic):
--    http://www.matf.bg.ac.rs/p/files/1607987415-24-rbpVezbe102020.html 
--    [instructions at the bottom of the page]

-- 1. Izdvojiti naziv i broj espb bodova za sve predmete
--     koji se predaju na fakultetu (PROJEKCIJA).
predmet[naziv]

-- PREDMET[idPredmeta, sifra, naziv, espb]
--                 (1, P34, 'Programiranje 1' ,6)
--                 (2, P3T, 'URBP', 5)
--                 (3, P45, 'RBP', 5)
--                 (4, P1, 'Analiza 1', 10)
-- PREDMET[naziv]:
-- ('Programiranje 1')
-- ('URBP')
-- ('RBP')
-- ('Analiza 1')

-- Projekcija:
-- Y = Attr(R)\X
-- R[X] = {x| x in Dom(X) AND (Exists y in Dom(Y)) (x,y) in R}
-- ex. R=predmet, X=(naziv), Y=(idPredmeta, sifra, espb)

-- 2. Izdvojiti sve detalje o studentima rodenim u Beogradu (Savski Venac)
--     (RESTRIKCIJA).
dosije
WHERE mestoRodjenja='Beograd (Savski Venac)'

-- Restrikcija: 
-- R[X=x] = {e | e in R AND X(e)=x}
-- p: R -> {T, F}
-- R[p] = {e | e in R AND p(e)}

-- 3. Prikazati detalje svih parova student ispit takvih da je student
--     polagao taj ispit (SLOBODNO SPAJANJE).
dosije TIMES ispit
WHERE dosije.indeks=ispit.indeks

-- ex.
-- dosije: [d1, d2]
-- ispit: [i1, i2, i3]
-- dosije TIMES ispit [(d1, i1), (d1, i2), (d1, i3), (d2, i1), (d2, i2), (d2, i3)]

-- R, Q relacije
-- Slobodno spajamo po binarnom predikatu p: RxQ -> {T, F}
-- R[p]Q = {(e,f) | e in R AND f in Q AND p(e,f)}
-- p - jednacenje po zajednickim attributima

-- 3. Prikazati detalje svih parova student ispit
--     takvih da je student polagao taj ispit.
--     Bez izdvajanja dva atributa sa vrednostima istog indeksa
--     (PRIRODNO SPAJANJE)
dosije JOIN ispit

-- Zargonski: JOIN := TIMES po zajednickim attr. + []
R[X*Y]Q = {(z,x,w) | (z,x) in R AND (y,w) in Q AND x=y}

-- 4. Izdvojiti oznake predmeta koji nose 3 ili 6 espb bodova (UNIJA).
(predmet WHERE espb=3)[oznaka]
UNION
(predmet WHERE espb=6)[oznaka]

(predmet WHERE espb=3 OR espb=6)[oznaka]

-- 5. Izdvojiti indekse studenata koji su ispite polagali sa ocenama
--     8 i 9 (INTERSECT).
(ispit WHERE ocena=8 AND status='o')[indeks]
INTERSECT
(ispit WHERE ocena=9 AND status='o')[indeks]

-- 6. Izdvojiti indekse studenata koji su sve ispite koje su polozili
--     polozili sa ocenom 10 (MINUS).
(ispit WHERE ocena=10 AND status='o')[indeks]
MINUS
(ispit WHERE ocena>5 AND ocena<10 AND status='o')[indeks]

-- 7. Napraviti spisak parova brojeva indeksa studenata
--     takvih da su oba rodjena u istom gradu.  (ALIJASI)
DEFINE ALIAS d1 FOR dosije
DEFINE ALIAS d2 FOR dosije

(d1 TIMES d2
WHERE d1.mestoRodjenja=d2.mestoRodjenja AND
             d1.indeks<d2.indeks)[d1.indeks, d2.indeks]

-- 8. Prikazati ime i prezime studenta koji je
--     polagao predmet ciji identifikator je 2001. 
((ispit WHERE idPredmeta=2001)[indeks]
JOIN
dosije[indeks, ime, prezime])[ime, prezime]

-- 9. Prikazati ime i prezime studenta koji je polozio
--     najmanje 1 predmet koji nosi 6 espb bodova.
--     Napomena: predmet sadrzi idPredmeta kao atribut (ne zove se id)
((ispit WHERE ocena>5 AND status='o')[indeks, idPredmeta]
JOIN
(predmet WHERE espb=6)[idPredmeta])[indeks]

(((ispit WHERE ocena>5 AND status='o')[indeks, idPredmeta]
JOIN
(predmet WHERE espb=6)[idPredmeta])[indeks]
JOIN
dosije[indeks, ime, preizme])[ime, preizme]

-- 10. Izdvojiti brojeve indeksa studenata koji su polagali sve predmete.
-- ex. Dosije(indeks, ime, prezime)
--                 (10, Pera, Peric)
--                 (45, Aca, Ilic)
--                 (34, Nikola, Nikolic)
--                 (67, Ana, Aleksic)
-- Ispit(indeks, naziv)
--        (10, URBP)
--        (10, P1)
--        (10, RBP)
--        (34, URBP)
--        (34, RBP)
--        (45, P1)
--        (34, P1)
-- Predmet(naziv)
--               (URBP)
--               (RBP)
--               (P1)
-- ispit DIVIDEBY predmet(indeks)
--                                        (10)
--                                        (34)
ispit[indeks, idPredmeta]
DIVIDEBY
predmet[idPredmeta]

-- Deljenje:
-- R, Q Relacije
-- Y skup atributa Y podskup Attr(R), X = Attr(R)\Y,  Z skup atributa Z=Attr(Q)
-- ex. R(X, Y), Q(Z)
R[Y%Z]Q = {x| x in R[X] AND {x} x Q[Z] in R} (in R[X])
-- Y = (idPredmeta), X=(indeks); Z=(idPredmeta)

--  11. Prikazati brojeve indeksa studenta koji su polozili bar one razlicite predmete koje je polagao 
--        student sa brojem indeksa 20130023.
(ispit WHERE ocena>5 AND status='o')[indeks, idPredmeta]
DIVIDEBY
(ispit WHERE indeks=20130023)[idPredmeta]

-- 12. Izdvojiti nazive svih predmeta koje su polozili svi studenti koji su upisali fakultet 2013. godine.
-- prvo samo idJeve
(ispit WHERE ocena>5 AND status='o')[idPredmeta, indeks]
DIVIDEBY
(dosije WHERE indeks>20130000 AND indeks<20140000)[indeks]

-- naziv predmeta "samo sminka":
((
	(ispit WHERE ocena>5 AND status='o')[idPredmeta, indeks]
	DIVIDEBY
	(dosije WHERE indeks>20130000 AND indeks<20140000)[indeks]
) JOIN predmet[idPredmeta, naziv])[naziv]

-- 13. Izdvojiti ime i prezime za svakog od studenata koji nisu polagali predmet ciji identifikator je 1021.
-- prvo indeks:
dosije[indeks]
MINUS
(ispit WHERE idPredmeta=1021)[indeks]

-- ime i prezime "samo sminka":
((
	dosije[indeks]
	MINUS
	(ispit WHERE idPredmeta=1021)[indeks]
) JOIN dosije[indeks, ime, prezime])[ime, prezime]

-- 14. Prikazati sifre svih predmeta koji nose 6 bodova ili ih je neko polozio u roku Januar 2015.
-- prvo idJevi
(predmet WHERE espb=6)[idPredmeta]
UNION
(ispit WHERE ocena>5 AND status='o' AND skGodina=2015 AND oznakaRoka='jan')[idPredmeta]

-- sifra triv.:
((
	(predmet WHERE espb=6)[idPredmeta]
	UNION
	(ispit WHERE ocena>5 AND status='o' AND skGodina=2015 AND oznakaRoka='jan')[idPredmeta]
) JOIN predmet[idPredmeta, sifra])[sifra]

-- 15. Prikazati imena i prezimena studenata koji imaju polozen neki ispit sa ocenom 6, i neki drugi polozen sa ocenom 10. 
-- opet prvo indekse:
(ispit WHERE ocena=6 AND status='o')[indeks]
INTERSECT
(ispit WHERE ocena=10 AND status='o')[indeks]

-- ime i prezime triv.:
((
	(ispit WHERE ocena=6 AND status='o')[indeks]
	INTERSECT
	(ispit WHERE ocena=10 AND status='o')[indeks]
) JOIN dosije[indeks, ime, preizme])[ime, prezime]

-- 16. Izdvojiti nazive svih ispitnih rokova u kojima je polagan predmet "Programiranje 1".
-- prvo skGodina i oznakaRoka
ispit[idPredmeta, skGodina, oznakaRoka]
JOIN
(predmet WHERE naziv='Programiranje 1')[idPredmeta]

-- naziv roka triv.:
((
	ispit[idPredmeta, skGodina, oznakaRoka]
	JOIN
	(predmet WHERE naziv='Programiranje 1')[idPredmeta]
) JOIN ispitniRok[skGodina, oznakaRoka, naziv])[naziv]

-- 17.  Izlistati spisak identifikatora predmeta koji nose manje bodova od predmeta ciji identifikator je 2004.
(predmet
WHERE espb<(predmet WHERE idPredmeta=2004)[espb])[idPredmeta] 
-- Poredjenje skalar < tabela!!!!

DEFINE ALIAS p1 FOR predmet
DEFINE ALIAS p2 FOR predmet 

(p1 TIMES p2
WHERE p2.idPredmeta=2004 AND p1.espb<p2.espb)[p1.idPredmeta]


-- VEZBANJE:
-- 1. Prikazati nazive svih predmeta koje je polozio student Nikola Vukovic.
(((dosije WHERE ime='Nikola' AND prezime='Vukovic')[indeks]
JOIN 
(ispit WHERE ocena>5 AND status='o')[indeks, idPredmeta])[idPredmeta]
JOIN predmet[idPredmeta, naziv])[naziv]

-- 2. Izdvojiti nazive svih predmeta koji su studenti rodeni u Beogradu polozili u Februaru 2015.
((ispit WHERE ocena>5 AND stauts='o')[indeks, idPredmeta, skGodina, oznakRoka]
JOIN 
(ispitniRok WHERE naziv='Februar 2015')[skGodina, oznakaRoka]
JOIN
(dosije WHERE mestoRodjenja='Beograd')[indeks]
JOIN 
predmet[idPredmeta, naziv]
)[naziv]

-- 3. Prikazati imena i prezimena svih studenata koji su polozili najmanje
--    jedan ispit koji je polozio student sa indeksom 20140025.
((ispit WHERE ocena>5 AND stauts='o')[indeks, idPredmeta]
JOIN 
(ispit WHERE indeks = 20140025 and ocena>5 AND status='o')[idPredmeta]
JOIN 
dosije[indeks, ime, preizme])[ime, prezime]

-- 4. Prikazati oznake i godine ispitnih rokova u kojima nijedan student iz
--    Kraljeva nije polozio nijedan predmet koji nosi 4 bodova.
ispitniRok[skGodina, oznakaRoka]
MINUS
(
    (dosije WHERE mestoRodjenja='Kraljevo')[indeks]
    JOIN
    (ispit WHERE ocena>5 AND status='o')[indeks, idPredmeta, skGodina, oznakRoka]
    JOIN
    (predmet WHERE espb=6)[idPredmeta]
)[skGodina, oznakaRoka]
