Primer 1.
 
Data je sledeća šema baze podataka S = (S, I ),    pri čemu je skup šema relacija:
  

S = { Odeljenje({    SIF_OD, IME_OD, GRAD} , {    SIF_OD} ),
Radnik({ SIF_RAD, IME, PREZIME,    RADMES, SIF_RUK, DATZAP, PLATA, STIMUL, SIF_OD}    , { SIF_RAD, SIF_OD }    )} ,

a skup međurelacionih ograničenja:

I = { Radnik[    SIF_RUK]  Í    Radnik[ SIF_RAD]    ,
Radnik[ SIF_OD]    Í Odeljenje[    SIF_OD] } .

Obeležja šema relacija imaju sledeća    značenja:
SIF_OD – šifra odeljenja,
GRAD – lokacija odeljenja,
SIF_RAD – šifra (matični broj)    radnika,
RADMES – naziv radnog mesta (dom(RADMES)={    analitičar, trg_putnik, službenik, prodavac, direktor}    )
SIF_RUK – šifra (matični broj)    radnika koji je neposredni rukovodilac datom radniku
DATZAP – datum zaposlenja
PLATA – mesečna    primanja radnika
STIMUL – iznos stimulacije u dinarima    za radnike koji su prodavci ili trgovački putnici
SIF_OD – šifra odeljenja u kome radnik radi.

Neka je rbp = { radnik,    odeljenje }  baza podataka nad šemom S.
 
Putem naredbi SQL-a realizovati    sledeće upite.
(NAPOMENA: Upiti se realizuju bez zalaženja    u sintaksne formalizme konkretnih softvera za rukovanje bazama podataka kao    što su: PROGRESS, ORACLE, FoxPro. Na primer: oznaka kraja SQL naredbe u ORACLE    softveru je simbol tačke-zareza (;), u PROGRESS-u tačka (.), u ACCESS-u simbol    tačke-zareza (;), u Visual FoxPro softveru nema simbola za oznaku kraja    SQL naredbe itd.)

PROSTI UPITI (PRETRAŽIVANJE BAZE PODATAKA)

1.1. Prikazati nazive i šifre odeljenja.

SELECT IME_OD, SIF_OD ODELJENJE 
FROM odeljenje

U ovom upitu se u listi atributa iza SELECT naredbe    nalazi ime ODELJENJE. To je naziv atributa u rezultujućoj tabeli, koji će zameniti    ime atributa IME_OD iz bazne relacije.

 
1.2. Prikazati sve podatke o radnicima koji rade u odeljenju    sa šifrom 20.

SELECT *
FROM radnik
WHERE SIF_OD = 20

1.3. Prikazati imena i matične    brojeve radnika i šifre odeljenja svih službenika.

SELECT IME, SIF_RAD, SIF_OD
FROM radnik
WHERE RADMES = ² službenik²    

   
Primena operatora: =, != (nije jednako ili <    > ), < (manje),    < = (manje ili jednako), >     (veće), > = (veće    ili jednako), između dve vrednosti (BETWEEN …AND…), lista vrednosti (IN lista),    poređenje znakova LIKE (za tipove podataka string) i nula – vrednost    (NULL), operator negacije NOT.

1.4. Prikazati imena odeljenja    i njihove šifre i to za ona odeljenja, čije su šifre veće od 10.

SELECT IME_OD, SIF_OD
FROM odeljenje
WHERE SIF_OD > 10

1.5. Prikazati imena, plate i    stimulacije za one radnike kod kojih je stimulacija veća od plate.

SELECT IME, PLATA, STIMUL
FROM radnik
WHERE STIMUL > PLATA

1.6. Prikazati imena, plate i šifre    odeljenja za trgovačke putnike iz odeljenja 20, čija je plata veća ili jednaka    od 400.

SELECT IME, PLATA, SIF_OD
FROM radnik
WHERE RADMES = ² trg_putnik²  
	AND SIF_OD = 20
	AND PLATA > = 400

Prava prenstva operatora

1.7. Prikazati podatke o svim analitičarima,    iz svih odeljenja, i o svim    službenicima odeljenja sa šifrom 10.

SELECT *
FROM radnik
WHERE RADMES = ² analitičar²     
	OR (RADMES = ² službenik²     AND SIF_OD = 10)

Zagrade u ovom upitu su nepotrebne, jer operator AND ima prvenstvno    u odnosu na OR, ali je ovaj način pregledniji.

1.8. Prikazati ime, naziv radnog mesta i šifru odeljenja za    upravnike koji ne rade u odeljenju 10.

SELECT IME, RADMES, SIF_OD
FROM radnik
WHERE RADMES = ² upravnik²  
	AND SIF_OD != 10

1.9. Prikazati sve podatke o radnicima koji    nisu upravnici ili službenici a rade u odeljenju 20.

SELECT *
FROM radnik
WHERE NOT (RADMES = ² upravnik²    OR RADMES = ² službenik²    )
	AND SIF_OD = 20

ili, upotrebom operatora IN:

SELECT *
FROM radnik
WHERE RADMES NOT IN (² upravnik²    , ² službenik²    )
	AND SIF_OD = 20

1.10. Prikazati imena radnika koji imaju drugo slovo imena    a.

SELECT IME
FROM radnik
WHERE IME LIKE ² _ _a²  

1.11. Prikazati imena, šifre odeljenja    i plate radnika odeljenja 20 uređene u rastućem redosledu atriubta PLATA.

SELECT IME, SIF_OD, PLATA
FROM radnik
WHERE SIF_OD = 20
ORDER BY PLATA

SPOJ RELACIJA
 
1.12. Kako se zovu gradovi u kojima rade radnici sa imenom    Mirko.

SELECT GRAD
FROM radnik, odeljenje
WHERE IME = ² Mirko²  
	AND radnik.SIF_OD = odeljenje.SIF_OD
	
ili:

SELECT GRAD
FROM radnik r, odeljenje o
WHERE IME = ² Mirko²  
	AND r.SIF_OD = o.SIF_OD

  
  
U ovim upitima u klauzuli WHERE u slučaju spoja relacija, koristimo    ili puno ime relacije (radnik, odeljenje) ili sinonime (r, o),    koji su navedeni u listi iza klauzule FROM.
Inače, ovaj tip spoja se zove i SPOJ NA JEDNAKOST    ili EQUI JOIN, zato što je operator    poređenja n-torki ovih dvaju relacija operator jednakosti (=).

SELF JOIN (SPAJANJE TABELE SAME SA SOBOM)
 
1.13. Prikazati imena i plate    svih radnika, koji imaju platu veću od plate radnika Markovića.

SELECT r1.IME, r1.PLATA, r2.IME, r2.PLATA
FROM radnik r1, radnik r2
WHERE r1.PLATA > r2.PLATA
	AND r2.PREZIME = ² Marković²    

U ovom upitu, relacija radnik se spaja sama sa sobom    na osnovu operatora >     (veće): r1.PLATA >  r2.PLATA. Svakoj n-torci    relacije r1 je pridružena n-torka sa vrednošću    obeležja PREZIME= ² Marković²     relacije r2, ako je zadovoljen uslov    da je vrednost obeležja PLATA n-torke relacije r1    veća od vrednosti istog obeležja n-torke relacije r2.

Operator spoljnog spoja (+) OUTER JOIN

Da bi se u rezultat upita uključile i one n-torke (oni redovi)    relacije koji ne zadovoljavaju uslov spajanja, koristi se operator + .

1.14. Prikazati podatke o odeljenjima,    imena radnika koji u njima rade, ali u rezultat upita uključiti i podatke o    odeljenjima, koji trenutno, možda, nemaju radnika.

SELECT o.SIF_OD, o.IME_OD, r.IME
FROM odeljenje o, radnik r
WHERE odeljenje.SIF_OD = radnik.SIF_OD (+)
ORDER BY SIF_OD

Simbol (+) u WHERE izrazu ima za posledicu da se relacija radnik    posmatra kao da sadrži još jedan red (n-torku) više, koji sadrži nula-vrednosti    za sve atribute. SQL spaja te redove tabele relacije radnik sa    bilo kojim redom tabele odeljenje, koji    se ne može spojiti sa stvarnim redom relacije radnik.

Upotreba sinonima relacija    u SQL upitima omogućava spajanje relacija samih sa sobom, na način kao da je    reč o dve posebne relacije. To se koristi naročito u slučajevima kada se želi    spojiti (udružiti) jedan red tabele sa drugim iz iste tabele, odnosno, kada    je u pitanju SELF JOIN.

  
  
1.15. Prikazati podatke o radnicima čija je plata veća od plate    njihovih rukovodilaca.

SELECT osoba.IME, osoba.PLATA, upravnik.IME, upravnik.PLATA
FROM radnik osoba, radnik upravnik
WHERE osoba.SIF_RUK = upravnik.SIF_RAD
AND osoba.PLATA > upravnik.PLATA

Rad sa numeričkim podacima

1.16. Prikazati ukupna    primranja radnika, čije je radno mesto trg_putnik.

SELECT IME, PLATA, STIMUL, PLATA+STIMUL
FROM radnik
WHERE RADMES = ² trg_putnik²  

1.17. Prikazati podatke o radnicima    čija je stimulacija veća od četvrtine njihovih plata.

SELECT IME, PLATA, STIMUL
FROM radnik
WHERE STIMUL > 0.25 * PLATA

Ovaj upit ilustruje situaciju    u kojoj se u WHERE izrazu može koristiti aritmetički izraz ili, u ORDER    BY klauzuli, što ilustruje sledeći upit.

1.18. Prikazati podatke o trgovačkim    putnicima po opadajućem redosledu odnosa stimulacije i plata.

SELECT IME, STIMUL/PLATA, STIMUL, PLATA
FROM radnik
WHERE RADMES = ² trg_putnik²  
ORDER BY STIMUL/PLATA DESC

1.19. Prikazati ukupna godišnja primanja prodavaca.
SELECT IME, PLATA, STIMUL, 12 * (PLATA + STIMUL)
FROM radnik
WHERE RADMES = ² prodavac²  
1.20. Prikazati dnevnu platu radnika iz odeljenja 20    (uzeti da mesec ima 22 radna dana) i zaokružiti    rezultat na dva decimalna mesta.

SELECT IME, PLATA, ROUND(PLATA/22,2)
FROM radnik
WHERE SIF_OD = 20

Ovaj upit ilustruje upotrebu funkcije    ROUND, koja zaokružuje broj na naznačen broj decimalnih mesta.

Grupne funkcije (AVG(), COUNT(), MAX(), MIN(), SUM() )

1.21. Prikazati prosečnu    platu službenika.

SELECT AVG(PLATA)
FROM radnik
WHERE RADMES = ² službenik²    

1.22. Prikazati prosečna    godišnja primanja trgovačkih putnika.

SELECT 12 * AVG( PLATA+STIMUL)
FROM radnik
WHERE RADMES = ² trg_putnik²  

Funkcija COUNT() računa broj numeričkih    vrednosti ili n-torki selektovanih pretraživanjem, koji imaju vrednost različitu    od nule (od nula-vrednosti).

1.23. Koliko radnika prima stimulaciju?

SELECT COUNT(STIMUL)
FROM radnik

Da bi se eliminisale višetruke    vrednosti atributa u n-torkama upotrebljava se izraz DISTINCT, odnosno upotrebom    ove klauzule funkcija COUNT() će odrediti broj različitih numeričkih vrednosti.  

1.24. Odrediti broj različitih    radnih mesta u odeljenju 20.

SELECT COUNT(DISTINCT RADMEST)
FROM radnik
WHERE SIF_OD = 20

Oblik funkcije COUNT(*) određuje    broj n-torki koji zadovoljavaju logički izraz u WHERE izrazu.

 
1.25. Koliko radnika radi u odeljenju 10?

SELECT COUNT(*)
FROM radnik
WHERE SIF_OD = 10

NAPOMENA: Ako se koristi grupna funkcija    u SELECT naredbi, onda se ne može izdvojiti pojedinačni rezultat. To    znači, na primer, da je pogrešna naredba: 

SELECT IME, AVG(PLATA)
Atribut IME ima vrednost za svaku n-torku , dok AVG(PLATA)    daje kao rezultat jednu vrednost za ceo upit. Kao ilustracija    ovog slučaja, poslužiće sledeći upit.

1.26. Koji radnik ima najveću    platu?

SELECT IME, PLATA
FROM radnik
WHERE PLATA = (SELECT MAX(PLATA)
			FROM radnik)

1.27. Kolika su ukupna primanja    trgovačkih putnika?

SELECT IME, PLATA, STIMUL, PLATA+STIMUL
FROM radnik
WHERE RADMES = ² trg_putnik²  
 
GROUP BY klauzula
 
1.28. Izračunati prosečnu platu za svako odeljenje.

SELECT SIF_OD, AVG(PLATA)
FROM radnik
GROUP BY SIF_OD

  
  
1.29. Izračunati prosečnu godišnju    platu za svako odeljenje, izuzimajući upravnike i direktora.

SELECT SIF_OD, 12 * AVG(PLATA)
FROM radnik
WHERE RADMES NOT IN (² upravnik²    , ² direktor²    )
GROUP BY SIF_OD

N-torke tabele moguće je grupisati    i po više atributa. To ilustruje sledeći primer.

 
 
1.30. Izračunati prosečnu platu za svako    radno mesto grupisano po odeljenju.

SELECT SIF_OD, RADMES, COUNT(*), 12 * AVG(PLATA)
FROM radnik
GROUP BY SIF_OD, RADMES

HAVING klauzula

Putem ove klauzule moguće je selektovati grupe    n-torki, pošto su te grupe već formirane sa GROUP BY klauzulom.

1.31. Prikazati prosečnu platu    za sve grupe radnih mesta, na kojima radi više od 2 radnika.

SELECT RADMES, COUNT(*), AVG(PLATA)
FROM radnik
GROUP BY RADMES
HAVING COUNT(*) > 2

1.32. Prikazati nazive radnih    mesta, za koje je prosečna plata veća od upravnikove plate.

SELECT RADMES, AVG(PLATA)
FROM radnik
GROUP BY RADMES
HAVING AVG(PLATA) > 
		(SELECT AVG(PLATA)
		 FROM radnik
		 WHERE RADMES = ² upravnik²    )

Rad sa nula-vrednostima (funkcija NVL() )

Numerička vrednost atributa nula    u relaciji je semantički drugačija od one vrednosti koja sadrži broj    nula (0). Vrednost nula ili null-vrednost    se pikazuje kao prazan prostor, a broj nula kao broj (0). Na primer, samo radnici    koji su raspoređeni na radno mesto trgovačkih putnika ili prodavaca    imaju stimulaciju, pa je za te n-torke vrednost atributa STIMUL relacije radnik    definisana (eventualno za one trgovačke putnike ili prodavce, koji nisu dobili    stimulaciju, jer nisu ispunili neke od uslova za to). Za sve ostale n-torke    relacije radnik vrednost atributa    STIMUL je neodređena (odn. neprimenjivo svojstvo), odnosno, kažemo da je to    nula-vrednost (NULL).

1.33. Prikazati podatke o radnicima koji nemaju stimulaciju.

SELECT IME, PLATA, STIMUL, RADMES
FROM radnik
WHERE STIMUL IS NULL

1.34. Koliko ima radnika u odeljenju 10 koji primaju platu    i stimulaciju.

SELECT COUNT(PLATA), COUNT(STIMUL)
FROM radnik
WHERE SIF_OD = 10

U slučaju da je potrebno sabrati vrednosti PLATA + STIMUL i    to za sve n-torke, potrebno je nula-vrednost zameniti nekom određenom numeričkom    vrednošću. Za to se koristi funkcija NVL(). 

1.35. Prikazati ukupna primanja za svakog    radnika posebno.

SELECT IME, PLATA, STIMUL, PLATA + NVL(STIMUL,0)
FROM radnik

U ovom upitu, sve nula-vrednosti atributa STIMUL u relaciji    radnik biće zamenjene numeričkom vrednošću    0.

1.36. Izračunati prosečnu stimulaciju,    prosečna primanja, kao i ukupna primanja za celo    preduzeće.

SELECT AVG(STIMUL), AVG(PLATA + NVL(STIMUL,0)), 
SUM(PLATA + NVL(STIMUL,0))
FROM radnik

PODUPITI

1.37. Prikazati imena i nazive radnih mesta radnika koji imaju    isto radno mesto kao i radnik Marković.

SELECT IME, RADMES
FROM radnik
WHERE RADMES = 
		(SELECT RADMES
		 FROM radnik
		 WHERE PREZIME = ²    Marković² )

Naredbe koje podržavaju WHERE izraz su: SELECT, UPDATE,    DELETE, INSERT i CREATE.

1.38. Koji radnici zarađuju više    od bilo kog radnika odeljenja 10.

SELECT IME, PLATA, SIF_OD
FROM radnik
WHERE PLATA > ANY
		(SELECT PLATA
		 FROM radnik
		 WHERE SIF_OD = 10)

Ako u prethodnom upitu umesto operatora ANY upotrebimo operator    ALL, pretraživanje će selektovati n-torke čija vrednost atributa PLATA je veća    od svih vrednosti dobijenih podupitom.

1.39. Prikazati podatke o radnicima iz odeljenja 10 sa istim    radnim mestom kao bilo ko iz odeljenja 20.

SELECT IME. RADMES
FROM radnik
WHERE SIF_OD = 10
	AND RADMES IN
		(SELECT RADMES
		 FROM RADNIK
		 WHERE SIF_OD = 20)

U slučaju ORACLE softvera moguće    je upoređivati više atributa u spoljašnjem i unutrašnjem upitu. Na primer, kao    u sledećem upitu.

1.40. Prikazati podatke o radnicima koji imaju isto radno mesto    i platu kao analitičar Jović.

SELECT IME, RADMES, PLATA
FROM radnik
WHERE (RADMES, PLATA) =
		(SELECT RADMES, PLATA
		 FROM radnik
		 WHERE PREZIME = ²    Jović² )

Mogući su i takvi oblici upita koji sadrže više uslova sa    podupitima, koji su spojeni operatorima AND i OR.

1.41. Prikazati podatke o radnicima    koji imaju isto radno mesto kao i Marković, ili istu ili veću platu kao Jović,    i to uređene prema nazivima radnih mesta, a zatim prema rastućem redosledu plata.

SELECT IME, RADMES, SIF_OD, PLATA
FROM radnik
WHERE RADMES =
		(SELECT RADMES
		 FROM radnik
		 WHERE PREZIME = ²    Marković² )
OR		PLATA > =
		(SELECT PLATA
		 FROM radnik
		 WHERE PREZIME = ²    Jović² )
ORDER BY RADMES, PLATA

Takođe, podupit može sadržati podupite (odn. ugnježdene    podupite).

1.42. Prikazati podatke o radnicima odeljenja 20 sa istim radnim    mestom kao bilo ko iz odeljenja ANALIZA.

SELECT IME, RADMES
FROM radnik
WHERE SIF_OD = 20 
AND RADMES IN
(SELECT RADMES
 FROM radnik
 WHERE SIF_OD =
(SELECT SIF_OD
 FROM odeljenje
 WHERE IME_OD = ² ANALIZA²    ))

Primena operatora unije (UNION), preseka (INTERSECT) i razlike    (MINUS)

Upit (spoljašnji ili unutrašnji) može    biti sastavljen od dva ili više SELECT blokova, koji su povezani operatorima    (UNION, INTERSECT, MINUS). To ilustruje sledeća slika (Marjanović Zoran, ORACLE    relacioni SUBP, Beograd, 1990, str. 31).



      
.

 
		
			
1.43. Prikazati podatke o radnicima čija    je plata jednaka plati koju ima radnik Marković ili Jović.

SELECT IME, PLATA
FROM radnik
WHERE PLATA IN
		(SELECT PLATA
		 FROM radnik
		 WHERE PREZIME = ²    Marković² 
		 UNION
		 SELECT PLATA
		 FROM radnik
		 WHERE PREZIME = ²    Vasić² )
Podupit može davati za rezultat    informacije iz više relacija. To ilustruje sledeći primer.

1.44. Koji radnici obavljaju isti    posao kao radnici koji rade u odeljenjima čija je lokacija Novi Sad.

SELECT IME, PREZIME, RADMES
FROM radnik
WHERE RADMES IN
		(SELECT RADMES
		 FROM radnik, odeljenje
		 WHERE odeljenje.GRAD = ²    Novi Sad² 
		 AND radnik.SIF_OD = odeljenje.SIF_OD)

 S obzirom da se informacije o lokaciji odeljenja u kojima    su zaposleni radnici nalaze u relaciji odeljenje, u podupitu je potrebno    spojiti relacije radnik i odeljenje    na osnovu istih vrednosti zajedničkih obeležja ovih relacija a to je obeležje    SIF_OD.

Do sada su bili navedeni primeri upita, kod kojih se podupit    izvršavao samo jednom, a rezultat podupita    se koristi u WHERE izrazu glavnog upita. Međutim, postoje i takvi upiti,    kod kojih se podupiti izvršavaju više puta, jednom za svaku n-torku koja    se koristi u glavnom upitu. To su korelisani upiti ili zavisni    ugdnježdeni upiti (Mogin P, Luković    I, Principi baza podataka, Novi Sad, 1996, str. 209)

1.45. Koji radnici zarađuju više    od prosečne plate za odeljenje u kome rade?
U ovom upitu glavni upiti će izgledati:
SELECT SIF_OD, IME, PLATA
FROM radnik
WHERE PLATA >     prosečne plate za odeljenje u kome radnik radi

Podupit će izgledati:
(SELECT AVG(PLATA)
FROM radnik
WHERE SIF_OD = šifra odeljenja za datog radnika)

Sada je jasno zašto se ovakvi upiti zovu zavisni    ugnježdeni upitii. Izvršavanje    podupita zavisi od rezultata spoljašnjeg (glavnog) upita. U ovom slučaju, šifra    odeljenja u podupitu zavisi od šifre odeljenja, koja je selektovana u    spoljašnjem upitu.
Upit ima konačni izgled:

SELECT SIF_OD, IME, PLATA
FROM radnik rX
WHERE PLATA > 
 (SELECT AVG(PLATA)
 FROM radnik rY
 WHERE rX.SIF_OD = rY.SIF_OD)

Upotreba operatora EXISTS

U slučaju upotrebe operatora EXISTS    glavni upit će se izvršiti ako unutrašnji upit kao rezultat pretraživanja ima    bar jednu n-torku. (Opširnije o ovom operatoru u primeru br. 3).

1.46. Prikazati podatke o radnicima    koji imaju najmanje jednog radnika koji im je podređen.

SELECT IME, PREZIME, RADMES, SIF_OD
FROM radnik rX
WHERE EXISTS
	(SELECT *
	 FROM radnik rY
	 WHERE rX.SIF_RAD = rY.SIF_RUK)

Ažuriranje baze podataka (naredbe INSERT, UPDATE i DELETE)

1.47. Uneti podatke o novom radniku.

INSERT INTO radnik
VALUES(7978, ² Zdravko²    , ² Čolić²    , ² analitičar²    , 7790, ² 01.05.99²    , 1000,NULL,20)

S obzirom da se radi o radniku koji obavlja posao analitičara,    pa nema pravo na stimulaciju, vrednost atributa STIMUL je nula-vrednost, odnosno,    NULL (po sintaksi ORACLE softvera).

  
U naredbi INSERT može se koristiti i podupit, pa se na taj    način mogu n-torke iz jedne relacije uneti u drugu. Podupit zamenjuje izraz    VALUES.

 


1.48. Svim analitičarima i upravnicima dati premiju u iznosu    od 10% njihovih plata. Te informacije uneti u relaciju premija zajedno    sa datumom zaposlenja.

INSERT INTO PREMIJA(SIF_RAD,PREMIJA, RADMES, DATZAP)
	SELECT SIF_RAD, 0.10 * PLATA, RADMES, DATZAP
	 FROM radnik
	 WHERE RADMES IN (² analitičar²    , ² upravnik²    )

1.49. Svim trgovačkim putnicima    i savetnicima iz odeljenja 10 povećati platu za 8%.

UPDATE radnik
	SET PLATA = PLATA * 1.08
	WHERE (RADMES = ² trg_putnik²    OR RADMES = ² savetnik²    )
	 AND SIF_OD = 10
  
Naredba UPDATE može da koriti i podupite u WHERE klauzuli.
1.50. Sve radnike koji su zaposleni u Novom Sadu rasporediti    na radno mesto službenika.

UPDATE radnik
	SET RADMES = ² službenik²    	
	WHERE SIF_OD IN
		(SELECT SIF_OD
		FROM odeljenje
		WHERE GRAD = ² Novi    Sad² )

1.51. Izbrisati podatke o svim radnicima koji rade u odeljenju    PRIPREMA.

DELETE radnik
WHERE SIF_OD IN (SELECT SIF_OD
			FROM odeljenje
			WHERE IME_OD = ²    PRIPREMA² )