U svakodnevnom radu sa bazama podataka često se stiče utisak da SQL upit “čita” redom kako je napisan: prvo SELECT, pa FROM, zatim WHERE, i tako dalje. Međutim, ispod te prividne logike krije se drugačiji, strogo definisan redosled izvršavanja. Razumevanje tog redosleda nije akademska sitnica, već temelj za pisanje ispravnog, efikasnog i predvidivog SQL koda.
Kako SQL zapravo razmišlja?
SQL je deklarativni jezik. Mi mu ne govorimo kako da nešto uradi, već šta želimo da dobijemo. Zbog toga redosled pisanja upita i redosled izvršavanja nisu isto.
Upit koji napišemo ovako:
ne izvršava se tim redom. Baza podataka ima svoj interni tok razmišljanja.
SQL klauzule se izvršavaju sledećim redosledom:
-
FROM
-
WHERE
-
GROUP BY
-
HAVING
-
SELECT
-
ORDER BY
-
LIMIT / OFFSET
Ovaj poredak je ključan za razumevanje samog izvršavanja neke SQL komande.
FROM – izbor sirovog materijala
Sve počinje od klauzule FROM. U ovom koraku baza podataka određuje iz kojih tabela (i kroz koje JOIN operacije) će uzeti podatke.
WHERE – filtriranje redova
Tek nakon toga dolazi WHERE. Ovde se uklanjaju redovi koji ne ispunjavaju uslov.
Važno je da se zapamti da WHERE ne može da koristi agregatne funkcije poput COUNT, SUM ili AVG, jer se u ovom trenutku grupisanje još nije dogodilo.
Zato je sledeći upit neispravan:
Baza u tom trenutku još ne zna šta je COUNT(*).
GROUP BY – stvaranje grupa
Ako upit sadrži GROUP BY, SQL sada grupiše preostale redove po zadatim kolonama.
Nakon ovog koraka više ne govorimo o pojedinačnim redovima, već o grupama redova. Ovo je trenutak kada agregatne funkcije dobijaju smisao.
HAVING – filtriranje grupa
Tek sada dolazi HAVING. Njegova uloga je slična WHERE klauzuli, ali radi nad grupama, a ne nad pojedinačnim redovima.
Drugim rečima:
-
WHERE filtrira redove pre grupisanja
-
HAVING filtrira grupe posle grupisanja
Ova razlika je jedna od najčešćih tačaka zabune kod početnika.
SELECT – oblikovanje rezultata
Tek u ovom koraku SQL obrađuje klauzulu SELECT. Ovde se bira koje kolone, izrazi i agregati će se pojaviti u konačnom rezultatu.
Zbog ovoga ne možete koristiti alias (broj) u WHERE ili HAVING klauzuli, on u tom trenutku još ne postoji.
ORDER BY – sortiranje rezultata
Kada je rezultat već formiran, SQL ga sortira.
Zanimljivo je da ORDER BY može koristiti alias iz SELECT klauzule, jer se izvršava posle nje.
LIMIT / OFFSET – ograničavanje izlaza
Na samom kraju, ako je navedeno, SQL ograničava broj vraćenih redova.
Ovo je poslednji korak i nema uticaja na logiku upita, samo na količinu prikazanih podataka.
