Koncept spajanja tabela i vrste spajanja
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:
-
INNER JOIN
-
LEFT JOIN (LEFT OUTER JOIN)
-
RIGHT JOIN (RIGHT OUTER JOIN)
-
FULL JOIN (FULL OUTER JOIN)
-
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.