Uvod

U modernim relacionim bazama podataka, podaci se čuvaju u više međusobno povezanih tabela. Te tabele retko postoje izolovano – one zajedno čine jedinstvenu celinu podataka. Da bismo iz više tabela dobili smislen rezultat, potrebno je da ih spojimo. SQL zato nudi poseban mehanizam koji se zove JOIN (spajanje tabela).

Spajanje tabela omogućava da se podaci iz više izvora uključe u jedan rezultat, pod određenim uslovima. Ovo je jedan od najvažnijih koncepata u bazi podataka, jer omogućava da iskorišćavamo relacionu strukturu baze.


1. Šta je spajanje tabela?

Spajanje tabela (JOIN) je SQL operacija koja kombinuje redove iz dve ili više tabela na osnovu logičkog odnosa između njih. Taj odnos je najčešće vezan preko ključeva:

  • primarni ključ (PRIMARY KEY) — jedinstveno obeležava red u tabeli

  • strani ključ (FOREIGN KEY) — povezuje jedan red sa redom iz druge tabele

Primer:

  • Tabela Učenici

  • Tabela Odeljenja

Tabela Učenici ima kolonu odeljenje_id koja je strani ključ ka tabeli Odeljenja.

JOIN je upravo mehanizam koji kaže: donesi mi podatke iz obe tabele, ali samo one koji pripadaju jednom drugom.


2. Zašto je spajanje važno?

Bez JOIN-ova, baze podataka bi bile samo skupovi nepovezanih podataka. JOIN omogućava:

  • prikaz kompleksnih informacija na jednom mestu,

  • izbegavanje dupliranja podataka,

  • efikasno čuvanje podataka u zasebnim tabelama,

  • logičko povezivanje informacija.


3. Vrste spajanja

Postoji više vrsta spajanja tabela. Najčešće su:

  1. INNER JOIN

  2. LEFT JOIN (LEFT OUTER JOIN)

  3. RIGHT JOIN (RIGHT OUTER JOIN)

  4. FULL JOIN (FULL OUTER JOIN)

  5. CROSS JOIN

U nastavku detaljno objašnjavamo svaku vrstu.


4. Primer tabela

Koristićemo sledeće dve tabele za objašnjenje:

Tabela: Učenici

id ime odeljenje_id
1 Ana 1
2 Marko 1
3 Jelena 2
4 Luka NULL

Tabela: Odeljenja

id oznaka
1 III-1
2 III-2
3 III-3

5. INNER JOIN

INNER JOIN vraća samo one redove koji imaju poklapanje u obe tabele.

SQL:

SELECT ime, oznaka
FROM Ucenici
INNER JOIN Odeljenja
ON Ucenici.odeljenje_id = Odeljenja.id;

Rezultat:

ime oznaka
Ana III-1
Marko III-1
Jelena III-2

Učenik Luka nema odeljenje, pa se ne pojavljuje u rezultatu.


6. LEFT JOIN

LEFT JOIN vraća sve redove iz leve tabele, a iz desne samo one koji imaju poklapanje.

Desna tabela popunjava se vrednostima NULL ako nema odgovarajućih vrednosti.

SQL:

SELECT ime, oznaka
FROM Ucenici
LEFT JOIN Odeljenja
ON Ucenici.odeljenje_id = Odeljenja.id;

Rezultat:

ime oznaka
Ana III-1
Marko III-1
Jelena III-2
Luka NULL

Vidimo da se Luka pojavljuje — ali bez oznake odeljenja.


7. RIGHT JOIN

Radi suprotno od LEFT JOIN-a — vraća sve iz desne tabele, a iz leve samo one koji se podudaraju.

SQL:

SELECT ime, oznaka
FROM Ucenici
RIGHT JOIN Odeljenja
ON Ucenici.odeljenje_id = Odeljenja.id;

Rezultat:

ime oznaka
Ana III-1
Marko III-1
Jelena III-2
NULL III-3

Odeljenje III-3 nema nijednog učenika.


8. FULL JOIN

FULL JOIN vraća sve redove iz obe tabele, bilo da se poklapaju ili ne.

(Napomena: nije podržan u svim SQL sistemima, npr. MySQL ga nema direktno.)

SQL:

SELECT ime, oznaka
FROM Ucenici
FULL JOIN Odeljenja
ON Ucenici.odeljenje_id = Odeljenja.id;

Rezultat:

ime oznaka
Ana III-1
Marko III-1
Jelena III-2
Luka NULL
NULL III-3

9. CROSS JOIN

CROSS JOIN pravi kartezijanski proizvod (DEKARTOV PROIZVOD)— svaki red iz prve tabele sparuje se sa svakim redom iz druge.

Ako jedna tabela ima 4 reda, a druga 3 → rezultat ima 12 redova.

Koristi se retko, najčešće za generisanje kombinacija.


10. Vežbe

Vežba 1 – INNER JOIN

Zadatak:
Prikaži imena učenika i oznake odeljenja, ali samo za učenike koji imaju dodeljeno odeljenje.

Rešenje:

SELECT ime, oznaka
FROM Ucenici
INNER JOIN Odeljenja
ON Ucenici.odeljenje_id = Odeljenja.id;

Vežba 2 – LEFT JOIN

Zadatak:
Prikaži sve učenike i njihova odeljenja, uključujući i one koji nisu razvrstani.

Rešenje:

SELECT ime, oznaka
FROM Ucenici
LEFT JOIN Odeljenja
ON Ucenici.odeljenje_id = Odeljenja.id;

Vežba 3 – Pronalaženje učenika bez odeljenja

Zadatak:
Pronađi samo one učenike koji nemaju dodeljeno odeljenje.

Rešenje:

SELECT ime
FROM Ucenici
LEFT JOIN Odeljenja
ON Ucenici.odeljenje_id = Odeljenja.id
WHERE Odeljenja.id IS NULL;

Vežba 4 – RIGHT JOIN

Zadatak:
Prikaži sva odeljenja i učenike u njima, uključujući prazna odeljenja.

Rešenje:

SELECT ime, oznaka
FROM Ucenici
RIGHT JOIN Odeljenja
ON Ucenici.odeljenje_id = Odeljenja.id;

Vežba 5 – FULL JOIN (ako baza podržava)

Zadatak:
Prikaži sve učenike i sva odeljenja, bez obzira na to da li se poklapaju.

Rešenje:

SELECT ime, oznaka
FROM Ucenici
FULL JOIN Odeljenja
ON Ucenici.odeljenje_id = Odeljenja.id;

11. Zadaci za proveru znanja (sa rešenjima)

Zadatak 1

Prikaži imena učenika i oznake odeljenja, ali izostavi učenike koji nemaju odeljenje.

Rešenje:

SELECT ime, oznaka
FROM Ucenici
INNER JOIN Odeljenja
ON odeljenje_id = Odeljenja.id;

Zadatak 2

Prikaži sva odeljenja i broj učenika u svakom od njih.

Rešenje:

SELECT oznaka, COUNT(Ucenici.id) AS broj_ucenika
FROM Odeljenja
LEFT JOIN Ucenici
ON Odeljenja.id = Ucenici.odeljenje_id
GROUP BY oznaka;

Zadatak 3

Prikaži listu učenika koji pripadaju odeljenju „III-1“.

Rešenje:

SELECT Ucenici.ime
FROM Ucenici
INNER JOIN Odeljenja
ON Ucenici.odeljenje_id = Odeljenja.id
WHERE Odeljenja.oznaka = 'III-1';

Zadatak 4

Prikaži sva odeljenja koja nemaju nijednog učenika.

Rešenje:

SELECT oznaka
FROM Odeljenja
LEFT JOIN Ucenici
ON Odeljenja.id = Ucenici.odeljenje_id
WHERE Ucenici.id IS NULL;

Zadatak 5 – Teži

Napravi listu učenika u formatu:

Ime učenika – Odeljenje
(ali ako učenik nema odeljenje umesto oznake prikaži: „nema odeljenje“)

Rešenje:

SELECT 
    ime,
    COALESCE(oznaka, 'nema odeljenje') AS odeljenje
FROM Ucenici
LEFT JOIN Odeljenja
ON Ucenici.odeljenje_id = Odeljenja.id;

Zaključak

Koncept spajanja tabela je fundamentalni deo rada sa relacionim bazama podataka. Razumevanje različitih tipova JOIN-ova omogućava jasno, efikasno i precizno dobijanje podataka iz više izvora. U praksi se najčešće koriste INNER i LEFT JOIN, dok su ostale vrste specifične za određene potrebe.

Last modified: Friday, 21 November 2025, 9:05 AM