Sunteți pe pagina 1din 11

Gruparea avansat a datelor

Pentru a obine linii agregat i superagregat corespunztoare expresiilor din clauza GROUP BY a unei cereri, se pot utiliza operatorii ROLLUP i CUBE sau opiunea GROUPING SETS. Operatorii ROLLUP i CUBE produc mulimi care conin liniile obinute n urma gruprii obinuite i linii pentru subtotaluri.

Operatorul ROLLUP
Operatorul ROLLUP poate fi folosit pentru extragerea de statistici i informaii totalizatoare din mulimile rezultate. Acest operator poate fi util la generarea de rapoarte, diagrame i grafice. Gruprile generate de ROLLUP sunt create prin deplasarea ntr-o singur direcie, i anume de la dreapta la stnga, de-a lungul listei de coloane specificate n clauza GROUP BY. Funcia agregat se aplic gruprilor astfel obinute. Specificarea a n expresii n operatorul ROLLUP conduce la crearea unui numr de n + 1 grupri. Liniile care se bazeaz pe valoarea primelor n expresii se numesc linii obinuite (sunt liniile obinute dac n clauza GROUP BY nu ar fi existat acest operator), iar celelalte se numesc linii superagregat. Pentru a produce subtotaluri pe baza a n coloane fr a utiliza operatorul ROLLUP, ar fi necesare n + 1 instruciuni SELECT legate prin operatorul UNION ALL. Acest lucru ar face execuia cererii ineficient deoarece fiecare instruciune SELECT determin accesarea tabelului, deci ar avea loc n + 1 accesri ale datelor. Operatorul ROLLUP determin rezultatele efectund un singur acces la tabel i este util atunci cnd sunt implicate multe coloane n producerea subtotalurilor. Exemplu. S se afieze codurile mai mici dect 200 ale prezentrilor de mod, codurile creatorilor care au realizat vestimentaii pentru aceste prezentri i suma valorilor vestimentaiilor pentru: fiecare dintre aceste prezentri i fiecare creator care a realizat vestimentaii expuse n prezentare; fiecare prezentare, indiferent de creator; toate prezentrile avnd codul mai mic dect 200, indiferent de codul creatorului. SELECT cod_prezentare, cod_creator, SUM(valoare) FROM vestimentatie WHERE cod_prezentare < 200 GROUP BY ROLLUP(cod_prezentare, cod_creator); Afiat n iSQL*Plus, rezultatul instruciunii precedente va fi de forma:

COD_PREZENTARE 33 33 33 77 77

COD_CREATOR 12 28 12

SUM(VALOARE) 25000 12000 37000 14700 14700 51700

Rezultatul instruciunii conine 3 tipuri de linii. Liniile obinuite (agregat) se caracterizeaz prin faptul c toate valorile lor sunt diferite de null. De exemplu, prima linie reprezint valoarea total a vestimentaiilor creatorului care are codul 12, expuse n prezentarea avnd codul 33. n mod similar se interpreteaz a doua i a patra linie din rezultat. Linia a treia i a cincea din rezultat conin valoarea total a vestimentaiilor din prezentarea al crei cod este 33, respectiv 77. Aceste linii se disting prin faptul c valoarea coloanei cod_creator este null. Ultima linie conine suma valorilor tuturor vestimentaiilor din prezentrile al cror cod este 33 sau 77. Valoarea afiat este obinut prin totalizarea valorilor de pe a treia, respectiv a cincea linie. Deoarece aceast linie corespunde totalului general, ea conine valoarea null pe toate coloanele, cu excepia cmpului SUM(valoare).

Operatorul CUBE
Spre deosebire de operatorul ROLLUP, care produce informaii superagregat doar pentru o parte dintre combinaiile posibile, CUBE produce subtotaluri pentru toate combinaiile posibile de grupri formate pe baza expresiilor specificate n clauza GROUP BY, precum i un total general. Gruprile generate de operatorul CUBE sunt realizate pe baza tuturor combinaiilor posibile ale expresiilor specificate. Operatorul returneaz cte o linie totalizatoare pentru fiecare grup. Acest operator este folosit pentru a produce mulimi de rezultate care sunt utilizate n rapoarte. Pentru o clauz GROUP BY care conine n coloane sau expresii, vor exista 2n combinaii posibile superagregat. Din punct de vedere matematic, aceste combinaii formeaz un cub n-dimensional, de aici provenind numele operatorului. Pentru producerea de subtotaluri fr ajutorul operatorului CUBE ar fi necesare 2n instruciuni SELECT legate prin operatorul UNION ALL, adic s-ar realiza 2n accesri ale datelor, ceea ce ar fi dezavantajos din punct de vedere al

performanelor. Exemplu. S se afieze codurile mai mici dect 200 ale prezentrilor de mod, codurile creatorilor care au realizat vestimentaii pentru aceste prezentri i suma valorilor vestimentaiilor pentru: fiecare dintre aceste prezentri i fiecare creator care a realizat vestimentaii expuse n prezentare; fiecare creator, indiferent de prezentare; fiecare prezentare, indiferent de creator; toate prezentrile avnd codul mai mic dect 200, indiferent de codul creatorului. SELECT cod_prezentare, cod_creator, SUM(valoare) FROM vestimentatie WHERE cod_prezentare < 200 GROUP BY CUBE(cod_prezentare, cod_creator); n iSQL*Plus, rezultatul instruciunii precedente va fi de forma urmtoare: COD_PREZENTARE 33 33 33 77 77 12 28 12 COD_CREATOR 12 28 SUM(VALOARE) 25000 12000 37000 14700 14700 39700 12000 51700 Rezultatul instruciunii conine 4 tipuri (2) de linii. Pe lng liniile care ar fi fost obinute cu ajutorul lui ROLLUP, operatorul CUBE a produs linii care reprezint suma valorilor vestimentaiilor pentru fiecare creator care a expus n prezentri avnd codul mai mic dect 200. Aceste linii se disting prin faptul c valoarea coloanei cod_prezentare este null.

Funcia GROUPING
O valoare null a unei expresii specificate n operatorii ROLLUP sau CUBE poate proveni din tabelul de baz, i se numete valoare null stocat, sau poate fi o valoare null creat de operaia ROLLUP sau CUBE ca rezultat al unei funcii grup

asupra expresiei respective. Pentru a arta modul cum a fost obinut o valoare null sau o valoare totalizatoare generat prin intermediul operatorilor CUBE i ROLLUP, se poate utiliza funcia GROUPING. Aceast funcie accept un singur argument, care trebuie s fie una dintre expresiile specificate n clauza GROUP BY, i returneaz valoarea 0 sau 1. Valoarea 0 returnat de funcia GROUPING pe baza unei expresii poate indica fie c expresia a fost utilizat pentru calculul valorii agregat, fie c valoarea null a expresiei este o valoare null stocat. Valoarea 1 returnat de funcia GROUPING pe baza unei expresii poate indica fie c expresia nu a fost utilizat pentru calculul valorii agregat, fie c valoarea null a expresiei este creat de ROLLUP sau CUBE ca rezultat al gruprii. Valorile returnate de funcia GROUPING sunt utile pentru determinarea nivelului de agregare al unui subtotal dat, adic a grupului sau grupurilor pe care se bazeaz subtotalul respectiv, sau identificarea provenienei unei valori null a unei expresii calculate, dintr-una din liniile mulimii rezultat. Exemplu. Se consider cererea enunat anterior, pentru operatorul ROLLUP. S se afieze modul n care intervin coloanele cod_prezentare i cod_creator n calculul valorilor agregat i superagregat. SELECT cod_prezentare, cod_creator, SUM(valoare) DECODE(GROUPING(cod_prezentare), 0, 'da ', 'nu ') int_prez, DECODE(GROUPING(cod_creator), 0, 'da ', 'nu ') int_cr FROM vestimentatie WHERE cod_prezentare < 200 GROUP BY ROLLUP(cod_prezentare, cod_creator); SUM INT_PREZ INT_CR (VALOARE) 25000 12000 37000 12 14700 14700 51700 da da da da da nu da da nu da nu nu

COD_PREZENTARE COD_CREATOR 33 33 33 77 77 12 28

Pentru a calcula valoarea de pe prima linie a rezultatului a fost luat n considerare att coloana cod_prezentare, ct i cod_creator. Prin urmare, expresiile GROUPING(cod_prezentare) i GROUPING(cod_creator) au valoarea 0 pentru prima linie din rezultat. Valoarea de pe linia a treia din rezultat a fost calculat lund n considerare doar coloana cod_prezentare, prin urmare GROUPING (cod_prezentare) i GROUPING(cod_creator) au valorile 0, respectiv 1. Niciuna dintre coloanele cod_prezentare i cod_creator nu au intervenit n calculul acestui total, prin urmare valorile corespunztoare expresiilor GROUPING(cod_prezentare) i GROUPING(cod_creator) sunt 1.

Clauza GROUPING SETS


Pentru a preciza anumite grupri multiple de date, pentru care se dorete obinerea de informaie agregat, este util clauza GROUPING SETS. Aceasta reprezint o extensie a clauzei GROUP BY, care permite scrierea unei singure instruciuni SELECT pentru a specifica grupri diferite, n loc de mai multe instruciuni SELECT combinate prin operatorul UNION ALL. Astfel, clauza GROUPING SETS mbuntete performanele cererii datorit faptului c realizeaz un singur acces la date. Spre deosebire de aceasta, reuniunea rezultatelor mai multor cereri este ineficient deoarece necesit mai multe parcurgeri ale acelorai date. Utilizarea acestei opiuni faciliteaz analiza datelor n mai multe dimensiuni. Gruprile specificate n aceast clauz pot conine operatorii ROLLUP i CUBE. Exemplu. Prin dou variante, considernd prezentrile al cror cod este mai mic dect 200, s se calculeze media valorilor vestimentaiilor: pentru fiecare prezentare i, n cadrul acesteia, pentru fiecare creator de mod; pentru fiecare creator de mod i, n cadrul acestuia, pentru fiecare model. SELECT cod_prezentare, cod_creator, cod_model, AVG(valoare) "Valoare medie" FROM vestimentatie WHERE cod_prezentare < 200 GROUP BY GROUPING SETS ((cod_prezentare, cod_creator), (cod_creator, cod_model)); Rezultatul acestei interogri conine valorile medii calculate asupra celor dou tipuri de grupri definite n clauza GROUPING SETS. n iSQL*Plus, rezultatul are forma urmtoare:

COD_PREZENTARE COD_CREATOR COD_MODEL 33 33 77 12 28 12 12 12 28 28

151 162 175 178

Valoare medie 4200 2750 3200 3820 1800 2200 1300

SELECT

cod_prezentare, cod_creator, NULL "model", AVG(valoare) "Valoare medie" FROM vestimentatie WHERE cod_prezentare < 200 GROUP BY cod_prezentare, cod_creator UNION ALL SELECT NULL, cod_creator, cod_model, AVG(valoare) "Valoare medie" FROM vestimentatie WHERE cod_prezentare < 200 GROUP BY cod_creator, cod_model; Varianta a doua de rezolvare poate fi ineficient, n condiiile n care lipsete un optimizor care analizeaz cererile componente i genereaz planul de execuie. Ineficiena provine din faptul c interogarea precedent va parcurge de dou ori tabelul vestimentatie. Prin urmare, este recomandat utilizarea extensiei GROUPING SETS. Operatorii ROLLUP i CUBE pot fi considerai cazuri particulare de mulimi de grupri definite cu ajutorul lui GROUPING SETS. De exemplu: ROLLUP(a, b, c) este echivalent cu GROUPING SETS ((a, b, c), (a, b), (a), ()); CUBE(a, b, c) poate fi rescris ca GROUPING SETS ((a, b, c), (a, b), (a, c), (b, c), (a), (b), (c), ()).

Coloane compuse
Tratarea unitar, n timpul calculelor asupra grupurilor, a anumitor colecii de coloane, se poate realiza prin definirea de coloane compuse. Lista de coloane care specific o coloan compus se include ntre paranteze. Coloanele compuse sunt utile n operaiile realizate cu ajutorul operatorilor ROLLUP, CUBE i al

clauzei GROUPING SETS. n CUBE sau ROLLUP coloanele compuse pot determina eliminarea agregrii de pe anumite niveluri. De exemplu, clauza GROUP BY ROLLUP(a, (b, c)) este echivalent cu urmtoarea instruciune compus (n care se precizeaz doar forma clauzelor GROUP BY): GROUP BY a, b, c UNION ALL GROUP BY a UNION ALL GROUP BY ( ) Se observ c (b, c) sunt tratate unitar, adic ROLLUP nu genereaz grupuri n care coloanele b i c nu apar simultan. Acest lucru este similar situaiei n care este definit un alias x pentru (b, c), iar specificaia clauzei GROUP BY este GROUP BY ROLLUP(a, x). Pentru a realiza totaluri generale (la nivelul ntregului tabel), gruparea corespunztoare este GROUP BY (), iar instruciunea SELECT care o conine are valori null pentru coloanele a i x. Forma acestei instruciuni este urmtoarea: SELECT null, null, coloan_agregat FROM nume_tabel GROUP BY (); Exemplu. S se afieze, furniznd dou variante de rezolvare (cu coloane compuse i, respectiv, cerere compus) urmtoarele informaii: valoarea medie a vestimentaiilor corespunztoare fiecrei prezentri; valoarea medie a vestimentaiilor pentru fiecare prezentare, iar n cadrul acesteia pentru fiecare creator de mod i fiecare model; media general a tuturor valorilor vestimentaiilor. SELECT cod_prezentare, cod_creator, cod_model, AVG(valoare) "Valoare medie" FROM vestimentatie GROUP BY ROLLUP (cod_prezentare, (cod_creator, cod_model)); SELECT cod_prezentare, cod_creator, cod_model, AVG(valoare) "Valoare medie" FROM vestimentatie GROUP BY cod_prezentare, cod_creator, cod_model UNION ALL SELECT cod_prezentare, TO_NUMBER(null), TO_NUMBER(null), AVG(valoare) "Valoare medie" FROM vestimentatie GROUP BY cod_prezentare UNION ALL SELECT TO_NUMBER(null), TO_NUMBER(null),

TO_NUMBER(null), medie" FROM vestimentatie GROUP BY ();

AVG(valoare)

"Valoare

Din considerentele prezentate anterior, se recomand evitarea cererilor compuse. Este indicat folosirea coloanelor compuse pentru asigurarea unei execuii eficiente.

Concatenarea gruprilor
O modalitate de a genera combinaii de grupri este furnizat de posibilitatea concatenrii mulimilor de grupri. Aceast operaie este util att pentru uurina scrierii cererilor, ct i pentru dezvoltarea de aplicaii. Codul SQL generat de aplicaiile OLAP implic deseori concatenarea mulimilor de grupri, n care fiecare astfel de mulime definete gruprile necesare pentru o dimensiune. Gruprile care vor fi concatenate se specific prin enumerarea mulimilor de grupri (grouping sets) i a operaiilor ROLLUP, CUBE separate prin virgul. De exemplu, GROUP BY GROUPING SETS(a, b), GROUPING SETS(c, d) definete gruprile (a, c), (a, d), (b, c), (b, d). Exemplu. S se determine media valorilor vestimentaiilor lund n considerare urmtoarele grupri: (cod_prezentare, cod_creator, cod_model), (cod_prezentare, cod_creator), (cod_prezentare, cod_model), (cod_prezentare). SELECT cod_prezentare, cod_creator, cod_model, AVG(valoare) FROM vestimentatie GROUP BY cod_prezentare, ROLLUP(cod_creator), CUBE(cod_model);

Funcii analitice
Asemntor funciilor agregat, funciile analitice realizeaz calcule pe baza unui grup de nregistrri. Spre deosebire de funciile agregat, pentru fiecare grup, funciile analitice pot returna mai multe linii rezultat. O funcie analitic poate aprea numai n clauzele SELECT sau ORDER BY. Aceast restricie este cauzat de faptul c funciile analitice reprezint ultimul set de operaii efectuat la procesarea unei interogri, naintea clauzei ORDER BY. Exemplu. Pentru fiecare vestimentaie, s se afle numrul de vestimentaii ale cror valori sunt cu cel mult 1000 mai mici i cu cel mult 2000 mai mari dect valoarea vestimentaiei respective. SELECT denumire, valoare, COUNT(*) OVER (ORDER BY valoare RANGE BETWEEN 1000 PRECEDING

AND FROM AS nr_vestimentatii vestimentatie;

2000 FOLLOWING)

Opiunea RANGE definete, pentru fiecare nregistrare, o mulime de linii corespunztoare. Funcia analitic va fi aplicat tuturor liniilor din aceast mulime.Cuvntul cheie OVER indic faptul c funcia opereaz pe mulimea de rezultate a cererii, adic dup evaluarea celorlalte clauze.

Interogri ierarhice
O baz de date relaional nu stocheaz nregistrrile n mod ierarhic. Dac exist o relaie ierarhic ntre liniile unui tabel, ierarhia corespunztoare poate fi construit printr-un proces de parcurgere a unui arbore (tree walking). O interogare ierarhic este o metod de furnizare, n ordine, a ramurilor arborelui. Direcia n care este parcurs ierarhia i stabilirea rdcinii ierarhiei rezult din relaia printe-copil a structurii arborescente create. O interogare ierarhic se formuleaz cu ajutorul clauzelor START WITH i CONNECT BY ale instruciunii SELECT. Clauza START WITH specific o condiie care identific liniile ce urmeaz s fie considerate ca rdcini ale cererii ierarhice respective. Dac se omite aceast clauz, sistemul Oracle utilizeaz toate liniile din tabel drept linii rdcin. Clauza CONNECT BY specific o condiie care identific relaia dintre liniile printe i copil ale ierarhiei. Condiia trebuie s conin operatorul PRIOR pentru a face referin la linia printe. Plasarea acestui operator determin direcia interogrii, dinspre printe spre copil (top-down) sau invers (bottom-up). Operatorul PRIOR poate fi plasat n faa oricrui membru al condiiei specificate n clauza CONNECT BY. Traversarea top-down, respectiv bottom-up a arborelui se realizeaz prin specificri de forma urmtoare: CONNECT BY PRIOR cheie_parinte = cheie_copil; CONNECT BY PRIOR cheie_copil = cheie_parinte; Primele linii printe ale interogrii sunt cele rdcin, identificate prin clauza START WITH. Pentru a gsi liniile copil, serverul evalueaz expresia din dreptul operatorului PRIOR pentru linia printe, i cealalt expresie pentru fiecare linie a tabelului. nregistrrile pentru care condiia este adevrat vor fi liniile copil. La pasul urmtor, acestea vor deveni linii printe i procedeul anterior se repet pn cnd nu mai sunt gsite linii copil. Spre deosebire de START WITH, n clauza CONNECT BY nu pot fi utilizate subcereri. n modelul referitor la gestiunea prezentrilor de mod, poate fi gndit o structur arborescent pe baza valorilor egale ale coloanelor data_start i

10

data_final din tabelul prezentare. Exemplu. S se afieze codul, denumirea, data debutului i data ncheierii prezentrilor, astfel nct fiecare prezentare s fie urmat de cele ncepute la data finalului su. Afiarea va ncepe cu prezentarea avnd codul 88. SELECT cod_prezentare, denumire, data_start, data_final FROM prezentare START WITH cod_prezentare = 88 CONNECT BY PRIOR data_final = data_start; Exemplu. Se cere afiarea cte unui mesaj de forma La data la care s-a incheiat prezentarea <nume_prezentare1> a inceput <nume_prezentare2> pentru fiecare linie din ierarhia descris anterior. Se vor considera doar prezentrile al cror organizator are codul 70. Prima linie afiat va fi cea corespunztoare prezentrii avnd numrul maxim de vestimentaii. SELECT 'La data la care s-a incheiat prezentarea '|| denumire || ' s-a achizitionat ' || PRIOR denumire "Traversare bottom-up " FROM prezentare START WITH cod_prezentare = (SELECT cod_prezentare FROM vestimentatie GROUP BY cod_prezentare HAVING COUNT(*) = (SELECT MAX(COUNT(*)) FROM vestimentatie GROUP BY cod_prezentare)) CONNECT BY PRIOR data_final = data_start AND cod_organizator = 70; Pe lng legtura dintre linia printe i cele copil, n clauza CONNECT BY se pot preciza i alte condiii suplimentare. Operatorul PRIOR poate fi utilizat i n cadrul acestor condiii, atunci cnd o coloan se refer la valoarea de pe linia printe. n clauza CONNECT BY a instruciunii precedente, coloana data_final este evaluat pentru linia printe, iar coloanele data_start i cod_organizator sunt evaluate pentru linia copil. Pseudocoloana LEVEL determin lungimea drumului de la rdcin la un nod n rezultatul unei cereri ierarhice. Exemplu. S se afieze ierarhia utilizat n exemplele precedente sub forma unui raport, folosindu-se indentri. Fiecare linie a tabelului va fi considerat drept rdcin. SELECT LEVEL,

11

LPAD(denumire, LENGTH(denumire) + (LEVEL * 2) - 2, '_') prezentari FROM prezentare CONNECT BY PRIOR data_final = data_start;

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