Sunteți pe pagina 1din 5

SUBQUERIES (SUBINTEROGARI)

In SQL, subinterogarile ne permit sa aflam o informatie care ne este necesara pentru a obtine
informatia pe care o vrem.
- O subinterogare (subquery) este o instructiune SELECT care este inclusa in clauza unei alte
instructiuni SELECT.
- Un subquery poate fi plasat in una din urmatoarele clauze: WHERE, HAVING si FROM.
- Subbquery-ul se executa prima data, iar rezultatul sau este folosit pentru obtinerea rezultatului de
catre interogarea principala (outer query).
EXEMPLU:
SELECT select_list
FROM table
WHERE expression operator
(SELECT select_list
FROM table);
REGULI DE FOLOSIRE A SUBINTEROGARILOR
- Un subquery se pune intre paranteze rotunde
- Un subquery este plasat in partea dreapta a unei conditii de comparare
- Interogarea exterioara si subquery-ul pot prelua date din tabele diferite
- Intr-o instructiune SELECT se poate folosi o singura clauza ORDER BY si, daca se foloseste, trebuie sa
fie ultima clauza a interogarii principale. Un subquery nu poate avea propria clauza ORDER BY.
- Singura limita a numarului de interogari este dimensiunea buffer-ului folosit de interogare.
- Daca subinterogarea returneaza null sau nu returneaza nici o linie, atunci interogarea exterioara nu
va returna nimic
Sunt doua tipuri de subinterogari(subqueries):
1) single-row subqueries care folosesc operatorii single-row: >,=,>=,<,<= si dau ca rezultat o
singura linie
2) multiple-row subqueries care folosesc operatorii multiple-row: IN, ANY, ALL si dau ca rezultat
mai multe linii
SINGLE ROW SUBQUERIES
SELECT last_name
FROM employees
WHERE salary >
(SELECT salary
FROM employees
WHERE initcap(last_name)=Abel );

Subinterogarea returneaza 11000, astfel instruciunea principala SELECT va returna toti angajatii cu
salariul mai mare decat 11000
SUBQUERIES FROM DIFFERENT TABLES (SUBINTEROGRILE DIN DIFERITE TABELE)
Subinterogrile nu sunt limitate la doar o interogare interioara
Subinterogrile nu sunt limitate doar la o interogare interioara. Pot exista mai mult de o
subinterogare care returneaza informaii la interogarea de exterior. De asemenea, interogrile de
exterior i interior pot obine date de la diferite tabele.

SELECT last_name, job_id, salary, department_id


FROM employees
WHERE job_id =
(SELECT job_id
FROM employees
WHERE employee_id =141)
AND department_id =
(SELECT department_id
FROM departments
WHERE location_id =1500);

Se pot folosi functiile de grup in subinterogari. O functie de grup utilizata in subquery fara clauza
GROUP BY, returneaza o singura linie.
Functiile de grup pot fi folosite in subinterogarile simple. Interogarea de interior returneaza un
singur rand interogarii de exterior.

SELECT last_name, first_name, salary


FROM f_staffs
WHERE salary <
(SELECT MAX(salary)
FROM employees
FROM f_staffs);

Subinterogarile pot fi plasate si in clauza HAVING. Deoarece clauza HAVING are intotdeauna o
conditie de grup, si subinterogarea va avea aproape intotdeauna o conditie de grup.
Clauza HAVING este folosita pentru selectia grupurilor si intotdeauna contine o conditie de grup (ca
MIN, MAX, SUM, AVG, COUNT).
SELECT department_id, MIN(salary)
FROM employees
GROUP BY department_id

HAVING MIN(salary) >


(SELECT MIN(salary)
FROM employees
WHERE department_id = 50);

APLICATII
1) Care este numele membrilor din personalul de la Global Fast Foods, al caror salariu este mai mare
decat angajatul cu ID-ul 12?
2) Care dintre angajatii Oracle au acelasi id al departamentului ca si cel corespunzator cu
departamentul IT?
1) Care este numele membrilor din personalul de la Global Fast Foods, al caror salariu este mai mare
decat angajatul cu ID-ul 12?
SELECT last_name
FROM f_staffs
WHERE salary >
(SELECT salary
FROM f_staffs
WHERE id = 12);
2) Care dintre angajatii Oracle au acelasi id al departamentului ca si cel corespunzator cu
departamentul IT?
SELECT first_name, last_name
FROM employees
WHERE department_id =
(SELECT department_id
FROM departments
WHERE department_name = 'IT');
MULTIPLE ROW SUBQUERIES
- Sunt acele subinterogari care dau ca rezultat mai multe valori.
- Folosesc operatorii multiple row: IN, ANY, ALL. Operatorul NOT poate fi folosit in combinatie cu
oricare dintre acestia.
IN
Operatorul IN este folosit daca in interogarea exterioara clauza WHERE este folosita pentru a selecta
acele valori care sunt egale cu una dintre valorile din lista returnata de subinterogare (inner query).
SELECT last_name, salary, department_id
FROM employees
WHERE salary IN =
(SELECT MIN(salary)
FROM employees

GROUP BY department_id);
ANY
- Acest operator este folosit atunci cand dorim ca interogarea exterioara sa selecteze valori egale,
mai mici sau mai mari decat cel putin o valoare dintre cele extrase de subquery.
SELECT title, producer
FROM d_cds
WHERE year < ANY
(SELECT year
FROM d_cds
WHERE producer = 'The Music Man');
ALL
Acest operator este folosit atunci cand dorim ca interogarea exterioara sa selecteze valori egale, mai
mici sau mai mari decat toate valoarile extrase de subquery.
SELECT title, producer,year
FROM d_cds
WHERE year > ALL
(SELECT year
FROM d_cds
WHERE producer = The Music Man);
VALORI NULL
Daca una dintre valorile returnate de subinterogarea multiple row este null, dar celelalte valori nu
sunt null, atunci:
- Daca sunt folositi operatorii IN sau ANY, interogarea exterioara va returna liniile care se potrivesc
cu valorile non-null.
- Daca este folosit operatorul ALL, interogarea exterioara nu va returna nimic.
GROUP BY si HAVING
- Pot fi folosite cu subinterogarile de tip multiple row.
SELECT department_id, MIN(salary)
FROM employees
GROUP BY department_id
HAVING MIN(salary) <ANY
(SELECT salary
FROM employees
WHERE department_id IN (10,20));
GROUP BY si HAVING
De asemenea, se poate folosi clauza GROUP BY intr-o subinterogare
SELECT department_id, MIN(salary)

FROM employees
GROUP BY department_id
HAVING MIN(salary) >ALL
(SELECT MIN(salary)
FROM employees
WHERE department_id < 50
GROUP BY department_id);
APLICATII
1) Gasiti numele (last_name) pentru toti angajatii ale caror salarii sunt aceleasi cu salariul minim din
oricare (any) departament.
SELECT last_name
FROM employees
WHERE salary = ANY
(SELECT MIN(salary)
FROM employees
GROUP BY department_id);
2) Scopul interogarii urmatoare este de a afisa salariul minim pentru fiecare departament al carui
salariu minim este mai mic decat cel mai mic salariu al angajatilor din departamentul 50.
Oricum, subinterogarea nu se executa deoarece are 5 erori. Gasiti erorile si corectati-le.
SELECT department_id
FROM employees
WHERE MIN(salary)
HAVING MIN(salary) >
GROUP BY department_id
SELECT MIN(salary)
WHERE department_id < 50;
Rezolvare
SELECT department_id, MIN(salary)
FROM employees
GROUP BY department_id
HAVING MIN(salary) <
(SELECT MIN(salary)
FROM employees
WHERE department_id = 50);

S-ar putea să vă placă și