11.02. Korelisani i nekorelisani podupiti
U SQL jeziku podupit (subquery) je upit koji se nalazi unutar drugog upita. On omogućava da koristimo rezultat jednog upita kao deo drugog. Podupiti se mogu koristiti u:
-
WHERE klauzuli
-
SELECT klauzuli (kao izraz kolone)
-
FROM klauzuli
U zavisnosti od toga da li podupit zavisi od glavnog upita ili ne, razlikujemo:
-
nekorelisane podupite
-
korelisane podupite
Primer baze podataka
Koristi se tabela Zaposleni sa sledećim kolonama: ID, Ime, Plata, Odeljenje (kao iz prethodne lekcije)
... (iste kao u prethodnoj lekciji) ... : pogledaj ako ih nema u bazi
Kreiranje tabele Zaposleni
CREATE TABLE Zaposleni (
ID INT PRIMARY KEY,
Ime VARCHAR(50),
Plata INT,
Odeljenje VARCHAR(30)
);
Popunjavanje tabele podacima
INSERT INTO Zaposleni (ID, Ime, Plata, Odeljenje) VALUES
(1, 'Ana', 60000, 'IT'),
(2, 'Marko', 55000, 'IT'),
(3, 'Ivana', 48000, 'HR'),
(4, 'Petar', 70000, 'IT'),
(5, 'Jelena', 48000, 'HR'),
(6, 'Milovan', 77000, 'Nabavke'),
(7, 'Sima', NULL, NULL);
1. Nekorelisani podupiti
Nekorelisani podupit je podupit koji se može izvršiti samostalno, nezavisno od glavnog upita.
To znači da ne koristi kolone iz spoljnog (glavnog) upita, izvršava se samo jednom, a njegov rezultat se prosleđuje glavnom upitu
Primer 1 – Plata iznad proseka firme
Imamo tabelu Zaposleni:
SELECT *
FROM Zaposleni
WHERE Plata > (SELECT AVG(Plata) FROM Zaposleni);
Objašnjenje:
-
Prvo se izvršava podupit:
SELECT AVG(Plata) FROM Zaposleni;On vraća jednu vrednost (npr. 60000).
-
Zatim glavni upit bira zaposlene čija je plata veća od tog proseka.
Podupit ne koristi podatke iz spoljnog upita – zato je nekorelisani.
Primer 2 – Zaposleni sa najvećom platom
SELECT *
FROM Zaposleni
WHERE Plata = (SELECT MAX(Plata) FROM Zaposleni);
Podupit vraća maksimalnu platu, a glavni upit pronalazi zaposlenog koji ima tu platu.
2. Korelisani podupiti
Korelisani podupit je podupit koji zavisi od glavnog upita.
To znači da koristi kolone iz spoljnog upita, izvršava se za svaki red glavnog upita i ne može se izvršiti samostalno.
Primer 1 – Plata iznad proseka odeljenja
SELECT Ime, Odeljenje, Plata
FROM Zaposleni Z1
WHERE Plata > (
SELECT AVG(Z2.Plata)
FROM Zaposleni Z2
WHERE Z2.Odeljenje = Z1.Odeljenje
);
Objašnjenje:
Za svakog zaposlenog se uzima se njegovo odeljenje, zatim se računa prosečna plata u tom odeljenju i tek onda se njegova plata poredi sa tim prosekom.
Pošto podupit koristi Z1.Odeljenje, on zavisi od spoljnog reda – zato je korelisani.
Primer 2 – Zaposleni sa najvećom platom u svom odeljenju
SELECT Ime, Odeljenje, Plata
FROM Zaposleni Z1
WHERE Plata = (
SELECT MAX(Z2.Plata)
FROM Zaposleni Z2
WHERE Z2.Odeljenje = Z1.Odeljenje
);
Ovaj upit pronalazi zaposlenog koji ima najveću platu unutar svog odeljenja.
Razlike:
| Osobina | Nekorelisani | Korelisani |
|---|---|---|
| Zavisi od glavnog upita | Ne | Da |
| Može se izvršiti samostalno | Da | Ne |
| Broj izvršavanja | Jednom | Za svaki red |
Vežbe
Zadatak 1: Pronaći zaposlene koji imaju platu manju od prosečne plate firme.
Zadatak 2: Pronaći zaposlene koji imaju najmanju platu u svom odeljenju.
< -- >