Sunteți pe pagina 1din 15

Subinterogri O subinterogare este o interogare inclus ntr-o alt interogare.

Rezultatul subinterogrii este utilizat de SGBD pentru a determina rezultatele interogrii de nivel mai nalt care conine subinterogarea. n forma sa cea mai simpl subinterogarea apare n clauzele WHERE sau HAVING ale altei interogri. S se afieze birourile n care planul de vnzri al biroului depete suma cotelor individuale ale agenilor.

Subinterogarea este cuprins ntre paranteze rotunde dar are forma unei instruciuni SELECT, cu o clauz FROM i clauzele opionale WHERE, GROUP BY i HAVING. Exist cteva diferene ntre o subinterogare i o instruciune SELECT. n majoritatea cazurilor, o subinterogare trebuie s furnizeze o singur coloan ca rezultat al interogrii. Aceasta nseamn c o subinterogare aproape ntotdeauna are un singur element n lista de selecie. Clauza ORDER BY nu poate fi menionat ntr-o subinterogare. Rezultatele subinterogrii sunt utilizate intern de ctre interogarea principal i nu sunt niciodat vizibile pentru utilizator, astfel nct nu are sens ordonarea acestora. Numele coloanelor care apar n subinterogare pot referi coloane ale tabelelor menionate n interogarea de baz. Subinterogri n clauza WHERE Subinterogrile apar cel mai adesea n clauza WHERE a instruciunii SELECT. n acest caz, subinterogarea acioneaz ca parte a procesului de selecie a liniilor. Cele mai simple subinterogri apar n interiorul condiiei de selecie. S se afieze agenii de vnzri ale cror cote sunt mai mici dect 10% din totalul planurilor de vnzri al tuturor birourilor.

S se afieze birourile n care planul de vnzri este mai mare dect suma cotelor agenilor de vnzri care lucreaz la biroul respectiv.

Subinterogarea produce o valoare diferit pentru fiecare birou, pe baza cotelor agenilor care lucreaz la biroul respectiv. Figura 5.21 ne arat, conceptual, cum efectueaz SQL aceast interogare. Interogarea principal i extrage datele din tabela OFFICES iar clauza selecteaz birourile care vor fi incluse n rezultatul interogrii. SQL parcurge una cte una liniile din tabela OFFICES i aplic testul specificat n clauza WHERE. Clauza WHERE compar valoarea coloanei TARGET din linia curent cu valoarea furnizat de subinterogare. Pentru a testa valoarea coloanei TARGET, SQL efectueaz subinterogarea i determin suma cotelor agenilor din biroul curent. Subinterogarea furnizeaz un singur numr i clauza WHERE compar acest numr cu valoarea coloanei TARGET, selectnd sau respingnd biroul curent n funcie de rezultatul comparaiei. Aa cum arat figura, SQL efectueaz subinterogarea n mod repetat, cte o dat pentru fiecare linie testat de clauza WHERE a interogrii principale.

Figura 5.21 Subinterogri n clauza WHERE Condiii de selecie n subinterogri Majoritatea produselor SQL ofer urmtoarele condiii de selecie n subinterogri: Comparaia Testarea apartenenei la o mulime Testul existenial Cuantificatorii (Operatorii ALL i ANY) Comparaia (=, <>, <, <=, >, >=) Compar valoarea unei expresii cu valoarea produs de o subinterogare. S se afieze agenii de vnzri ale cror cote sunt mai mari sau egale dect planul de vnzri al biroului din Atlanta.

S se afieze clienii servii de Bill Adams.

S se afieze toate produsele fabricate de firma ACI pentru care cantitatea din stoc este mai mare dect cantitatea din produsul ACI-41004 aflat n stoc.

Testarea apartenenei la o mulime (IN)

Compar valoarea unei coloane cu valorile furnizate de o subinterogare i returneaz TRUE dac valoarea coloanei coincide cu cel puin una dintre valorile produse de subinterogare. S se afieze agenii de vnzri care lucreaz n birouri care si-au depit planul.

S se afieze agenii de vnzri care nu lucreaz n birourile al cror manager este Larry Fitch (angajatul 108).

S se afieze toi clienii care au comandat produsul ACI Widgets (fabricant ACI, id-ul produsului ncepnd cu 4100) ntre Ianuarie i Iunie 1990.

Testul existenial (EXISTS) Verific dac o subinterogare produce vreo linie n rezultat. Acest test este utilizat numai n subinterogri. S se afieze produsele pentru care s-a primit cel puin o comand mai mare sau egal cu $25.000.

Conceptual, SQL proceseaz aceast interogare parcurgnd tabela PRODUCTS i efectund subinterogarea pentru fiecare produs. Subinterogarea produce o coloan care conine numrul fiecrei comenzi pentru produsul curent n valoare mai mare de $25.000. Dac exist astfel de comenzi (aadar coloana nu este vid), testul furnizeaz TRUE. Dac subinterogarea nu produce nici o linie, testul EXISTS furnizeaz FALSE. Testul EXISTS nu poate produce valoarea NULL. Putem inversa valoarea de adevr a testului EXISTS, utiliznd forma NOT EXISTS. n acest caz testul este TRUE dac subinterogarea nu produce linii i FALSE, n caz contrar. 6

Observm c testul EXISTS nu utilizeaz de fapt rezultatele interogrii. Verific doar dac o subinterogare produce vreun rezultat. Din acest motiv, SQL permite utilizarea clauzei SELECT * ntr-o subinterogare care conine testul existenial. Interogarea precedent poate fi scris astfel:

S se afieze toi clienii repartizai lui Sue Smith care nu au efectuat comenzi de peste $25.000.

S se afieze birourile n care lucreaz un agent de vnzri a crui cot reprezint mai mult de 55% din planul de vnzri al biroului respectiv.

Cuantificatorii (Operatorii ANY i ALL) SQL furnizeaz doi operatori de cuantificare, ANY i ALL, care extind operatorii de comparare. Ambii compar valoarea dintr-o coloan cu valorile furnizate de o subinterogare. Operatorul ANY este utilizat mpreun cu unul dintre cei ase operatori de comparaie (=, < >, <, <=, >, >=) pentru a compara valoarea unei coloane cu valorile furnizate de o subinterogare. Dac valoarea acestei coloane coincide cu vreuna dintre valorile furnizate de subinterogare, condiia este evaluat TRUE. S se afieze agenii care au primit o comand a crei valoare depete 10% din cota lor de vnzri.

S se afieze numele i vrsta tuturor agenilor care nu conduc nici un birou.

ntotdeauna se poate transforma o interogare care conine operatorul ANY ntr-o interogare care conine operatorul EXISTS prin mutarea comparaiei n interiorul

condiiei de selecie a subinterogrii. Aceasta este o bun idee deoarece interogrile care utilizeaz operatorul ANY sunt mai greu de formulat. n continuare este prezentat o formulare alternativ a interogrii precedente, utiliznd operatorul EXITS..

Operatorul ALL , ca i operatorul ANY, este utilizat mpreun cu unul dintre cei ase operatori de comparaie (=, < >, <, <=, >, >=) pentru a compara valoarea unei coloane cu valorile furnizate de o subinterogare. Dac valoarea acestei coloane coincide cu fiecare dintre valorile furnizate de subinterogare, condiia este evaluat TRUE. S se afieze birourile (i planurile lor de vnzri) n care toi agenii au realizat vnzri cu 50% mai mari dect planul de vnzri al biroului respectiv.

Subinterogri i Join Multe dintre interogrile pe care le-am scris utiliznd subinterogri pot fi scrise, de asemenea, utiliznd join-ul. SQL ne permite s exprimm interogrile n fiecare dintre cele dou moduri.

S se afieze numele i varsta agenilor care lucreaz la birouri situate n regiunea Western.

Subinterogarea furnizeaz lista birourilor din regiunea Western iar interogarea principal determin agenii care lucreaz la unul dintre acestea. n continuare este prezentat o alternativ a acestei interogri, utiliznd join-ul a dou tabele.

Aceast form a interogrii efectueaz join-ul dintre tabelele SALESREPS i OFFICES pentru a determina regiunea n care lucreaz fiecare dintre ageni i i elimin din rezultatul interogrii pe cei care nu lucreaz n regiunea Western. Fiecare dintre cele dou forme ale interogrii va determina rezultatul corect. Multe dintre interogrile care conin subinterogri nu pot fi exprimate ntr-o form echivalent utiliznd join-ul. De exemplu, s considerm urmtoarea interogare: S se afieze numele i vrsta agenilor care au cota de vnzri peste valoarea medie.

10

n acest caz, interogarea interioar este una sintetizatoare n timp ce interogarea principal nu. Aadar nu exist nici o modalitate de a combina cele dou interogri ntruna singur, prin utilizarea join-ului. Subinterogri imbricate Toate interogrile prezentate pn acum n acest subcapitol au avut dou nivele de interogare, cuprinznd o interogare principal i o subinterogare. Aa cum putem utiliza o subinterogare ntr-o interogare principal, putem utiliza o subinterogare ntr-o alt subinterogare. n continuare este prezentat un exemplu de interogare cu trei nivele. S se afieze clienii ai cror reprezentani de vnzri lucreaz la un birou din regiunea Eastern.

11

n acest exemplu, interogarea cea mai din interior:

furnizeaz o coloan care conine codul fiecrui birou din regiunea Eastern. Urmtoarea subinterogare:

furnizeaz o coloan care conine id-urile agenilor care lucreaz la unul dintre birourile selectate anterior. n final, interogarea cea mai din exterior:

determin clienii ai cror reprezentani de vnzri au unul dintre aceste id-uri. Aceeai tehnic utilizat n aceast interogare cu trei nivele poate fi utilizat pentru a formula interogri cu patru sau mai multe nivele. Standardul ANSI/ISO SQL nu precizeaz un numr maxim de nivele imbricate dar interogrile cu un numr mare de nivele de imbricare sunt dificil de citit i de neles. Subinterogri corelate Conceptual, SQL proceseaz subinterogarea pentru fiecare linie care intervine n interogare principal. Totui, n cazul multor subinterogri, se obine acelai rezultat pentru fiecare linie din interogarea principal. De exemplu, s considerm interogarea: S se afieze birourile ale cror vnzri se situeaz peste media planului de vnzri.

n aceast interogare, media planului de vnzri este aceeai pentru toate birourile; este complet independent de biroul curent. Ca urmare, SQL poate procesa aceast interogare

12

efectund mai nti subinterogarea i determinnd media planului de vnzri ($550.000) i apoi transformnd interogarea de baz astfel:

Produsele comerciale SQL detecteaz automat astfel de situaii i utilizeaz aceste artificii de calcul pentru a reduce volumul de calcule cerute de o subinterogare. Totui aceste artificii de calcul nu pot fi utilizate n cazul subinterogrilor care conin referine externe. S se afieze birourile al cror plan de vnzri depete totalul cotelor agenilor care lucreaz la biroul respectiv.

Pentru fiecare linie din tabela OFFICES, coloana OFFICE (care apare n interogare ca o referin extern) are valori diferite. Astfel, SQL trebuie s efectueze subinterogarea de cinci ori, cte o dat pentru fiecare linie din tabela OFFICES. O subinterogare care conine o referin extern (outer) este numit uneori i subinterogare corelat, deoarece rezultatele ei sunt corelate cu fiecare dintre liniile interogrii prrincipale. Subinterogri n clauza HAVING Dei subinterogrile sunt cel mai adesea prezente n clauza WHERE, ele pot fi utilizate i n clauza HAVING a unei subinterogri. Cnd o subinterogare apare n clauza HAVING, acioneaz ca o parte a condiiei de selecie a grupurilor de linii. S se afieze agenii a cror valoare medie a comenzilor primite pentru produsele fabricate de ACI este mai mare dect valoarea medie a tuturor comenzilor.

13

Figura 5.22 ne arat, conceptual, cum lucreaz aceast interogare. Subinterogarea determin valoarea medie a comenzilor. Este o subinterogare simpl, care nu conine referine externe, aadar SQL va calcula media o singur dat i o va utiliza repetat n clauza HAVING. Interogarea principal parcurge tabela ORDERS determinnd produsele fabricate de AICI i le grupeaz dup agenii de vnzri. Apoi, clauza HAVING verific fiecare grup pentru a vedea dac valoarea medie a comenzilor pentru grupul respectiv este mai mare dect media calculat anterior. Dac este aa, grupul este reinut; n caz contrar este eliminat. n final, clauza SELECT produce cte o linie sintetizatoare pentru fiecare grup, artnd numele agenilor de vnzri i valoarea medie a comenzilor.

Figura 5.22 Subinterogare n clauza HAVING

14

De asemenea, se poate utiliza o subinterogare corelat n clauza HAVING. Deoarece subinterogarea este evaluat pentru fiecare linie din grup, toate referinele externe din subinterogarea corelat trebuie s aib aceeai valoare pentru toate liniile din grup. Aceasta nseamn c referinele externe trebuie s se refere la o coloan de grupare sau s fie coninut ntr-o funcie de grup. S se afieze agenii ale cror valori medii ale comenzilor primite pentru produsele fabricate de ACI sunt mai mari sau egale cu valoarea medie a tuturor comenzilor primite de agentul respectiv.

n acest exemplu, subinterogarea determin media tuturor comenzilor pentru agentul considerat n clauza HAVING. Subinterogarea selecteaz comenzile corespunztoare unui anumit agent , utiliznd referina extern EMPL_NUM. Aceast referin extern este corect deoarece EMPL_NUM are aceeai valoare pentru toate liniile din grup.

15