Descărcați ca doc, pdf sau txt
Descărcați ca doc, pdf sau txt
Sunteți pe pagina 1din 12

1

SUBINTEROGARI

Obiective
Dupa parcurgerea acestei lectii, veti avea cunostintele
necesare pentru a realiza urmatoarele:
Descrierea tipurilor de probleme pe care le pot rezolva
subinterogarile;
Definirea subinterogarilor;
Listarea tipurilor de subinterogari;
Scrierea subinterogarilor single-row si multiple-row.

Scopul lectiei
n aceasta lectie se vor studia caracteristici mai avansate ale instructiunii
SELECT. Se pot scrie subinterogari n clauza WHERE a altei instructiuni SQL n
scopul obtinerii de valori bazate pe o valoare necunoscuta a unei conditii. Aceasta
lectie acopera att subinterogarile single-row, ct si cele multiple-row.

Folosirea unei subinterogari


pentru a rezolva o problema
Cine primeste un salariu mai mare dect cel al lui Jones ?
Cerere principala
Ce angajat are un salariu mai mare dect Jones ?

Subinterogare
?

Folosirea unei subinterogari pentru a rezolva o problema


Sa presupunem ca doriti sa scrieti o interogare pentru a afla cine cstiga un
salariu mai mare dect salariul lui Jones.
Pentru rezolvarea acestei probleme este nevoie de doua interogari: o interogare
pentru a afla ce salariu cstiga Jones si o a doua pentru a determina cine cstiga mai
mult dect aceasta suma.

Problema poate fi rezolvata combinnd aceste doua interogari, integrnd una


din cereri n cealalta.
O cerere inclusa sau subinterogare returneaza o valoare folosita de catre
interogarea exterioara sau principala. Folosirea unei subinterogari este echivalenta
executarii a doua cereri secventiale si folosirii rezultatului primei cereri ca valoare de
cautare pentru cea de a doua cerere.

Subinterogari
SELECT
FROM
WHERE

select_list
table
expr operator
(SELECT
FROM

select_list
table);

Subinterogarea (cererea interna) se executa o singura data


naintea interogarii principale.
Rezultatul subinterogarii este utilizat de catre cererea
principala (cererea externa).
Subinterogari
O subinterogare reprezinta o instructiune SELECT care este inclusa ntr-o
clauza apartinnd altei instructiuni SELECT. Se pot astfel construi instructiuni mai
puternice pornind de la instructiuni simple prin utilizarea subinterogarilor. Acestea pot
fi foarte folositoare n cazurile n care se doreste selectarea unor rnduri dintr-un tabel
cu o conditie care depinde de datele din tabelul propriu-zis.
Subinterogarile pot fi plasate n urmatoarele clauze SQL:
WHERE;
HAVING;
FROM.
n sintaxa mai sus prezentata:
operator
implica unul din urmatorii operatori de comparatie: >, = sau IN.
Nota: Operatorii de comparare se mpart n doua clase:
operatori single-row : >, =, >=, <, <>, <=
operatori multiple-row : IN, ANY, ALL.
Subinterogarea este deseori referita ca fiind o instructiune SELECT inclusa,
sub-SELECT sau instructiune SELECT interna. n general, subinterogarea se executa
prima, iar rezultatul este folosit pentru a finaliza conditia de cerere pentru interogarea
principala sau externa.

Utilizarea unei subinterogari


SQL> SELECT ename
2 FROM emp
2975
3 WHERE sal >
4
(SELECT sal
5
FROM emp
6
WHERE empno=7566);

ENAME
---------KING
FORD
SCOTT

Utilizarea unei subinterogari


n figura anterioara, cererea interna determina salariul angajatului cu numarul
7566. Cererea externa preia rezultatul cererii interne si l foloseste pentru a afisa toti
angajatii care cstiga un salariu mai mare dect aceasta suma.

Sfaturi n utilizarea subinterogarilor


Includerea subinterogarilor n paranteze.
Plasarea subinterogarilor n partea dreapta a operatorului
de
comparare.
A nu se adauga clauza ORDER BY ntr-o subinterogare.
Folosirea operatorilor single-row n subinterogari singlerow
Folosirea operatorilor multiple-row n subinterogari
multiple-row
Orientari n utilzarea subinterogarilor
O subinterogare trebuie sa fie inclusa ntre paranteze.
O subinterogare trebuie sa apara n partea dreapta a unui operator de
comparare.
Subinterogarile nu pot contine clauza ORDER BY. Pentru o instructiune
SELECT poate exista doar o singura clauza ORDER BY, iar daca aceasta
clauza este specificata, ea trebuie sa fie ultima clauza din instructiunea
SELECT principala.
3

Subinterogarile folosesc doua clase de operatori de comparare: operatori


single-row si operatori multiple-row.

Tipuri de subinterogari
Subinterogari single-row
Cerere principala
Subinterogare

FUNCTIONAR (CLERK)

Subinterogari multiple-row
Cerere principala
Subinterogare

FUNCTIONAR (CLERK)
MANAGER

Subinterogari multiple-column
Cerere principala
Subinterogare

FUNCTIONAR (CLERK) 7900


MANAGER
7698

Tipuri de subinterogari

Subinterogari single-row : cereri care returneaza doar un rnd din


instructiunea SELECT interna
Subinterogari multiple-row : cereri care returneaza mai mult de un rnd din
instructiunea SELECT interna
Subinterogari multiple-column : cereri care returneaza mai multe coloane
din instructiunea SELECT interna.

Subinterogari single-row
Returneaza doar un rnd
Folosesc operatori de comparare single-row
Operator

=
>
>=
<
<=
<>

Semnificatie
Egal cu
Mai mare dect
Mai mare sau egal cu
Mai mic dect
Mai mic sau egal cu
Diferit de
4

Subinterogari single-row
O subinterogare single-row este acea subinterogare care returneaza un singur
rnd din instructiunea SELECT interna. Acest tip de subinterogare foloseste un
operator single-row. Figura anterioara prezinta lista operatorilor single-row.
Exemplu:
Afisarea angajatilor care lucreaza pe acelasi post ca si angajatul ce are
numarul 7369.
SQL> SELECT ename, job
2
FROM emp
3
WHERE job=
4
(SELECT job
5
FROM emp
6
WHERE empno=7369);

ENAME
--------------JAMES
SMITH
ADAMS
MILLER

JOB
-----------FUNCTIONAR (CLERK)
FUNCTIONAR (CLERK)
FUNCTIONAR (CLERK)
FUNCTIONAR (CLERK)

Executarea unei subinterogari single-row


SQL> SELECT ename, job
2
FROM emp
3
WHERE job =
FUNCTIONAR
4
(SELECT job
5
FROM emp
6
WHERE empno = 7369)
7
AND
sal >
8
(SELECT sal
1100
9
FROM emp
10
WHERE empno = 7876);

ENAME
---------MILLER

JOB
--------CLERK

Executarea unei subinterogari single-row


O instructiune SELECT poate fi considerata ca un bloc de cereri. Exemplul de
mai sus afiseaza angajatii al caror post este acelasi cu cel al angajatului cu numarul
7369 si a caror salariu este mai mare dect cel al angajatului 7876.
Exemplul este format din 3 blocuri de cereri: o cerere exterioara si doua cereri
interne. Blocurile de cereri interne snt primele executate, producnd rezultatele
cererii: FUNCTIONAR (CLERK), respectiv 1100. Blocul exterior de cereri este apoi

procesat si foloseste valorile returnate de catre cererile interne pentru a finaliza


propriile conditii de cautare.
Ambele cereri interne returneaza valori singulare (FUNCTIONAR si 1100),
astfel ca aceasta instructiune SQL este denumita o subinterogare single-row.
Nota: Interogarile exterioare si incluse pot prelua datele din tabele
diferite.

Utilizarea functiilor de grup ntr-o subinterogare


SQL> SELECT ename, job, sal
2 FROM emp
3 WHERE sal =
4
(SELECT
5
FROM
ENAME
JOB
---------- --------SMITH
CLERK

800
MIN(sal)
emp);
SAL
--------800

Utilizarea functiilor de grup ntr-o subinterogare


n interogarea principala pot fi afisate date prin utilizarea unei functii de grup
ntr-o subinterogare care sa returneze un singur rnd. Subinterogarea se va plasa ntre
paranteze si dupa operatorul de comparare.
Exemplul din figura precedenta afiseaza numele, postul si salariul tuturor
angajatilor al caror salariu este egal cu salariul minim. Functia MIN (functie de grup)
returneaza o singura valoare (si anume, 800), care este folosita de catre interogarea
principala.

Clauza HAVING n subinterogare


Server-ul de ORACLE executa mai nti subinterogarile
Server-ul de ORACLE returneaza rezultatele catre clauza
HAVING a interogarii principale
SQL> SELECT
deptno, MIN(sal)
2 FROM
emp
3 GROUP BY
deptno
4 HAVING MIN(sal) >
800
5
(SELECT MIN(sal)
6
FROM emp
7
WHERE deptno = 20);

Clauza HAVING n subinterogari

Subinterogarile pot fi folosite nu numai n clauza WHERE, dar si n clauza


HAVING. Server-ul de Oracle executa subinterogarea, returnnd apoi rezultatul catre
clauza HAVING a subinterogarii principale.
Instructiunea SQL prezentata n figura de mai sus are ca scop final afisarea
tuturor departamentelor la nivelor carora salariul minim are o valoare mai mare dect
valoarea salariului minim din cadrul departamentului 20.
DEPTNO
-------------

10
30

MIN(SAL)
----------------

1300
950

Exemplu: Se cere sa se gaseasca postul avnd cel mai scazut salariu mediu:
SQL> SELECT job, AVG(sal)
2
FROM emp
3
GROUP BY job
4
HAVING AVG(sal) = (SELECT MIN(AVG(sal))
5
FROM emp
6
GROUP BY job);

Ce este gresit in instructiunea urmatoare?


SQL> SELECT empno, ename
2
FROM emp
3
WHERE sal =
4
(SELECT MIN(sal)
5
FROM
emp
6
GROUP BY deptno);

Operator single-row avnd ca termen drept o subinterogare


multiple-row
EROARE:
ORA-01427: subinterogarea single-row returneaza mai mult de un rnd
nici un rnd nu este selectionat

Erori ce pot apare la folosirea subinterogarilor


O eroare obisnuita la folosirea subinterogarilor o reprezinta returnarea a mai
mult de un rnd de catre o subinterogare dorita a fi de tip single-row.
n instructiunea SQL din exemplul anterior, subinterogarea contine o clauza
GROUP BY dupa numarul departamentului (deptno), care implica selectarea mai
multor rnduri, cte unul pentru fiecare grup gasit. n acest caz, rezultatul
subinterogarii va consta di valorile 800, 1300 si, respectiv 950.

Interogarea externa preia rezultatele subinterogarii (800, 1300, 950) si le


foloseste n clauza WHERE. Clauza WHERE contine un operator egal ( = ), operator
single-row de comparare, care asteapta o singura valoare de partea sa dreapta.
Operatorul = nu poate accepta mai mult de o valoare primita de la subinterogare si
astfel este generata eroarea.
Pentru a corecta eroarea, operatorul egal ( = ) trebuie nlocuit cu operatorul IN.

O astfel de instructiune functioneaza ?


SQL>
2
3
4
5
6

SELECT ename, job


FROM emp
WHERE job =
(SELECT job
FROM emp
WHERE ename='SMYTHE');

Subinterogarea nu returneaza nici o valoare


nici un rnd nu este selectat

Probleme ce pot apare la utilizarea subinterogarilor


O problema obisnuita legata de subinterogari o constituie posibilitatea
neselectarii nici unui rnd de catre interogarea inclusa.
n ceea ce priveste instructiunea SQL de mai sus, subinterogarea contine o
clauza WHERE (ename = SMYTHE). Se presupune ca intentia este de a selecta
angajatul cu numele Smythe. Instructiunea pare a fi corecta, dar la executie nu se
selecteaza nici un rnd.
Problema este ortografierea gresita a cuvntului Smythe. Nu exista nici un
angajat cu numele de Smythe. Astfel, subinterogarea nu va selecta nici un rnd.
Interogarea externa preia rezultatul subinterogarii (nul, n acest caz) si foloseste acest
rezultat n propria-i clauza WHERE. Interogarea externa nu gaseste nici un angajat
avnd cmpul referitor la post de valoare nula si astfel nu returneaza nici un rnd.

Subinterogari multiple-row
Selecteaza mai mult de un rnd
Folosesc operatori multiple-row de comparare
Operator
IN

Semnificatie
Egal cu oricare din elementele listei

Compara valoarea cu fiecare valoare


ANY
returnata de subinterogare luata separat
Subinterogari multiple-row
Compara valoarea cu toate valorile
ALL
returnate de subinterogare
8

Subinterogarile care returneaza mai mult de un rnd se numesc subinterogari


multiple-row. n cazul subinterogarilor multiple-row se folosesc operatori multiplerow, n locul celor single-row. Operatorul multiple-row necesita una sau mai multe
valori.
SQL> SELECT ename, sal, deptno
2
FROM emp
3
WHERE sal IN (SELECT MIN(sal)
4
FROM emp
5
GROUP BY deptno);

Exemplu:
Se cere sa se selecteze angajatii care cstiga un salariu egal cu salariul minim
la nivel de departament.
Interogarea interna va fi prima executata producnd ca raspuns la cerere trei
rnduri: 800, 950, 1300. Blocul cererii externe este apoi procesat si foloseste valorile
returnate de catre interogarea inclusa pentru a-si finaliza propria conditie de cautare.
De fapt, interogarea principala este privita din perspectiva server-ului Oracle astfel:
SQL> SELECT ename, sal, deptno
2 FROM emp
3 WHERE sal IN (800, 950, 1300);

Utilizarea operatorului ANY n subinterogarile multiple-row


SQL> SELECT empno, ename, job
2
FROM emp
800
3
WHERE sal < ANY
4
(SELECT sal
950
5
FROM emp
6
WHERE job = 'CLERK')
7
AND job <> 'CLERK';

1300
1100

EMPNO
ENAME JOB
--------- ---------- --------7654 MARTIN SALESMAN
7521 WARD
SALESMAN

Subinterogari multiple-row (continuare)


Operatorul ANY (si operatorul SOME, sinonim acestuia) compara o valoare
cu fiecare valoare returnata de subinterogare. Exemplul de mai sus afiseaza angajatii
ale caror salarii snt mai mici dect al oricarui functionar (clerk) si care nu snt
functionari. Salariul maxim pa care l cstiga un functionar este $1300. Instructiunea
SQL afiseaza toti angajatii care nu snt functionari, dar cstiga mai putin de $1300.
< ANY
nseamna mai mic dect maxim.
> ANY
nseamna mai mare dect minim.
= ANY
este echivalent cu operatorul IN.

10

Utilizarea operatorului ALL n subinterogarile multiple-row


SQL> SELECT empno, ename, job
2
FROM emp
3
WHERE sal > ALL
2916.6667
4
(SELECT avg(sal)
5
FROM emp
6
GROUP BY deptno);

EMPNO
--------7839
7566
7902
7788

ENAME
---------KING
JONES
FORD
SCOTT

1566.6667
2175

JOB
--------PRESIDENT
MANAGER
ANALYST
ANALYST

Subinterogari multiple-row (continuare)


Operatorul ALL compara o valoare cu toate valorile returnate de o
subinterogare. Exemplul de mai sus afiseaza toti angajatii ale caror salarii snt mai
mari dect salariile medii la nivel de departamente.. Cel mai mare salariu mediu al
vreunui departament este $2916.6667, asa ca interogarea va selecta acei angajati ale
caror salarii snt mai mari dect $2916.6667.
> ALL
nseamna mai mare dect maxim
< ALL
nseamna mai mic dect minim
Operatorul NOT poate fi folosit cu operatorii IN, ANY si ALL.

REZUMAT
Subinterogarile snt folositoare atunci cnd o cerere se
bazeaza pe valori necunoscute.
SELECT
FROM
WHERE

select_list
table
expr operator
(SELECT select_list
FROM table);

10

11

Rezumat
O subinterogare este o instructiune SELECT inclusa ntr-o clauza a altei
instructiuni SQL. Subinterogarile snt folositoare atunci cnd interogarea se
bazeaza pe criterii necunoscute.
Subinterogarile au urmatoarele caracteristici:
Pot transmite un rnd de date instructiunii principale care contine un
operator single-row, precum: =, <>, >, >=, < sau <=;
Pot transmite rnduri multiple de date instructiunii principale care
contine un operator multiple-row, precum: IN, ANY sau ALL;
Snt primele procesate de catre server-ul Oracle, iar clauzele WHERE
si HAVING folosesc rezultatele;
Pot contine functii de grup.

Privire generala asupra lucrarii practice


Creare de subinterogari pentru obtinerea de valori bazate
pe criterii necunoscute
Folosire subinterogari pentru a determina ce valori apartin
unui set de date si nu altuia

Privire generala asupra exercitiilor


n aceasta lucrare practica se vor scrie interogari complexe folosind
instructiuni SELECT incluse.
Chestionare
Exista posibilitatea de a se dori ca, pentru nceput, sa fie creata interogarea
interna pentru ntrebarile urmatoare. Fiti siguri ca ea ruleaza si produce datele
anticipate nainte de a codifica interogarea principala.
1.
2.
3.
4.
5.
6.

Exercitii:
Sa se scrie o interogare care sa afiseze numele angajatului si data angajarii pentru
toti angajatii din acelasi departament ca Blake. Sa se exclude Blake.
Sa se creeze o cerere pentru a afisa numarul angajatului si numele sau pemtru toti
angajatii care cstiga mai mult dect salariul mediu. Sa se sorteze rezultatele n
ordinea descrescatoare a salariului.
Sa se scrie o cerere care va afisa numarul si numele angajatului pentru toti cei care
lucreaza ntr-un departament care detine cel putin un angajat al carui nume contine
litera T . Salvati instructiunea ntr-un fisier denumit p6q3.sql.
Afisati numele angajatului, numarul departamentului si postul pe care lucreaza
acesta pentru toti angajatii al caror departament este situat n Dallas.
Afisati numele si salariul tuturor angajatilor subordonati lui King.
Afisati numarul departamentului, numele si postul tuturor angajatilor din
departamentul de vnzari (sales).
11

12

7. Modificati p6q3.sql pentru a afisa numarul, numele si salariul tuturor angajatilor


care cstiga mai mult dect salariul mediu si, totodata, lucreaza ntr-un departament
care detine cel putin un angajat ce contine n numele sau litera T . Salvati
fisierul ca p6q7.sql. Reexecutati interogarea.

12

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