11.02. Podupiti kao izrazi kolona
Uvod
Podupit (engl. subquery) je SQL upit koji se nalazi unutar drugog upita. Kada se podupit koristi u delu za kolone (SELECT deo), on se ponaša kao izraz kolone – što znači da za svaki red glavnog upita vraća jednu vrednost.
Ovakvi podupiti se najčešće koriste za prikaz zbirnih vrednosti (prosek, maksimum, minimum, zbir), poređenje vrednosti jednog reda sa podacima iz druge tabele, dodavanje dodatnih informacija bez spajanja tabela (JOIN) i slično.
Podupit kao izraz kolone piše se u okviru SELECT dela:
SELECT kolona1,
(SELECT ... ) AS naziv_kolone
FROM tabela;
Pravilo je da :
Podupit koji se koristi kao izraz kolone mora da vrati tačno jednu vrednost (jedan red i jednu kolonu) za svaki red glavnog upita.
Tabele koje koristimo u nastavku su Ucenik i Ocena
Ucenik
CREATE TABLE Ucenik (
UcenikID INT PRIMARY KEY,
Ime VARCHAR(50) NOT NULL,
Odeljenje VARCHAR(10)
);
Unos podataka:
INSERT INTO Ucenik (UcenikID, Ime, Odeljenje) VALUES (1, 'Marko', 'III-1'), (2, 'Ana', 'III-2'), (3, 'Luka', 'III-1');
Ocena
CREATE TABLE Ocena (
OcenaID INT PRIMARY KEY,
UcenikID INT,
Predmet VARCHAR(50),
Ocena INT,
FOREIGN KEY (UcenikID) REFERENCES Ucenik(UcenikID)
);
Unos podataka:
INSERT INTO Ocena (OcenaID, UcenikID, Predmet, Ocena) VALUES (1, 1, 'Matematika', 5), (2, 1, 'Informatika', 4), (3, 2, 'Matematika', 5), (4, 3, 'Informatika', 3), (5, 3, 'Matematika', 4);
Primer 1:
Za tabelu Ucenik ispisati ime svakog od učenika i ukupan broj učenika u školi.
SELECT Ime,
(SELECT COUNT(*) FROM Ucenik) AS UkupanBrojUcenika
FROM Ucenik;
Objašnjenje:
Podupit (SELECT COUNT(*) FROM
Ucenik) računa ukupan broj učenika. Pošto vraća jednu vrednost, može se koristiti kao kolona. Ta vrednost će se ponoviti u svakom redu rezultata.
Primer 2 – Korelisani podupit
Želimo da za svakog učenika prikažemo njegov prosk.
SELECT Ime,
(SELECT AVG(Ocena)
FROM Ocena
WHERE Ocena.UcenikID = Ucenik.UcenikID) AS Prosek
FROM Ucenik;
Objašnjenje:
Ovo je korelisani podupit jer koristi vrednost iz glavnog upita (Ucenik.UcenikID).
Za svakog učenika posebno računa se prosek njegovih ocena.
Za primere u nastavku se koristi tabela Zaposleni
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);
Primer 3: Razlika između plate zaposlenog i prosečne plate
SELECT Ime,
Plata,
Plata - (SELECT AVG(Plata) FROM Zaposleni) AS RazlikaOdProseka
FROM Zaposleni;
Objašnjenje:
Ovde podupit postaje deo matematičkog izraza.
Dobijamo informaciju koliko je plata zaposlenog iznad ili ispod proseka.
Primer 4: Broj zaposlenih u istom odeljenju (korelisani podupit)
SELECT Ime,
Odeljenje,
(SELECT COUNT(*)
FROM Zaposleni Z2
WHERE Z2.Odeljenje = Z1.Odeljenje) AS BrojUOdeljenju
FROM Zaposleni Z1;