27-30. 01. Ispitivanje pripadnosti skupu (IN i NOT IN)
U radu sa bazama podataka često se javlja potreba da se proveri da li neka vrednost pripada određenom skupu vrednosti. Taj skup može biti unapred poznat ili dobijen kao rezultat drugog SQL upita. SQL jezik za ovu namenu ima operatore IN i NOT IN, koji omogućavaju jednostavno i pregledno ispitivanje pripadnosti skupu bez potrebe za pisanjem složenih uslova.
Ovi operatori se veoma često koriste zajedno sa podupitima, jer podupiti mogu da vrate skup vrednosti koji se zatim koristi za poređenje u glavnom upitu.
Pojam ispitivanja pripadnosti skupu
Ispitivanje pripadnosti skupu podrazumeva proveru da li se vrednost nekog atributa nalazi među vrednostima koje čine određeni skup.
- Operator IN proverava da li vrednost pripada skupu.
- Operator NOT IN proverava da li vrednost ne pripada skupu.
Skup vrednosti može biti:
- eksplicitno naveden (lista vrednosti),
- rezultat podupita (najčešći slučaj u praksi).
Korišćenje operatora IN
Operator IN vraća rezultat tačno ako se vrednost izraza nalazi u skupu vrednosti koji sledi iza operatora.
Opšti oblik
SELECT kolone
FROM tabela
WHERE kolona IN (skup_vrednosti);
... tabele koje koristimo su 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');
... ali dodati još dva zaposlena:
INSERT INTO Zaposleni VALUES
(6, 'Milovan', 77000, 'Nabavke'),
(7, 'Sima', NULL, NULL);
Primer 1: IN sa unapred zadatim vrednostima
Prikazati zaposlene koji rade u IT ili HR odeljenju.
SELECT Ime, Odeljenje
FROM Zaposleni
WHERE Odeljenje IN ('IT', 'HR');
U ovom primeru se proverava da li vrednost kolone Odeljenje pripada skupu koji čine vrednosti 'IT' i 'HR'.
IN sa podupitom
Mnogo češći slučaj je korišćenje operatora IN zajedno sa podupitom. Podupit u ovom slučaju vraća skup vrednosti koji se koristi u glavnom upitu za poređenje.
Primer 2: IN sa podupitom
Prikazati zaposlene koji rade u odeljenjima u kojima postoji bar jedan zaposleni sa platom većom od 60.000.
SELECT Ime, Odeljenje
FROM Zaposleni
WHERE Odeljenje IN (
SELECT Odeljenje
FROM Zaposleni
WHERE Plata > 60000
);
Objašnjenje:
-
Podupit pronalazi sva odeljenja u kojima postoji plata veća od 60.000.
-
Glavni upit prikazuje zaposlene čije se odeljenje nalazi u tom skupu.
Korišćenje operatora NOT IN
Operator NOT IN predstavlja negaciju operatora IN. On vraća rezultat tačno ako se vrednost ne nalazi u skupu vrednosti.
Opšti oblik
SELECT kolone
FROM tabela
WHERE kolona NOT IN (skup_vrednosti);
Primer 3: NOT IN sa podupitom
Prikazati zaposlene koji ne rade u IT odeljenju.
SELECT Ime
FROM Zaposleni
WHERE ID NOT IN (
SELECT ID
FROM Zaposleni
WHERE Odeljenje = 'IT'
);
U ovom primeru se iz rezultata izostavljaju svi zaposleni koji pripadaju IT odeljenju (čak i oni zaposleni koji nemaju navedeno odeljenje).
Jednostavnija varijanta ovog upita (bez podupita, samo sa navođenjem vredbosti u zagradama), ali ako negde ima null, ne vraća isto, jer neće biti navedeni zaposleni kod kojih je nepopunjeno polje za odeljenje:
SELECT Ime
FROM Zaposleni
WHERE Odeljenje NOT IN ('IT' );
Napomena koja se tiče NULL vrednosti
Pri korišćenju operatora NOT IN, potrebno je obratiti pažnju na NULL vrednosti. Ako podupit vrati makar jednu NULL vrednost, rezultat NOT IN uslova može biti neočekivan (upit može vratiti prazan skup).
Zbog toga se u praksi često koristi EXISTS kao sigurnija alternativa.
Poređenje sa operatorima ALL i ANY
Operator IN se može posmatrati kao jednostavniji i čitljiviji oblik poređenja sa operatorom ANY kada se koristi operator jednakosti.
Primer:
kolona IN (podupit)
funkcionalno odgovara:
kolona = ANY (podupit)
Zadaci za samostalan rad
-
Prikazati zaposlene koji rade u odeljenjima gde postoji plata manja od 50.000.
-
Prikazati zaposlene koji ne rade u odeljenju „Finansije“.
-
Napisati upit koji koristi IN operator i podupit sa agregatnom funkcijom:
-
Ispisati zaposlene za odeljenja gde postaji bar jedan zaposleni sa minimalcem.
-