Sunteți pe pagina 1din 24

Laborator nr.

2 - SQL
6. Utilizarea funciilor agregat
Deseori este necesar s sintetizm datele fr a le regsi propriu-zis n totalitate, iar SQL
pune la dispoziie funcii speciale n acest scop. Utiliznd aceste funcii, interogrile SQL sunt
frecvent folosite la regsirea datelor pentru analiz i includerea n rapoarte. Printre exemplele
din aceast categorie de operaii de regsire se numr:
Determinarea numrului de rnduri dintr-un tabel (sau a numrului de rnduri care satisfac o
anumit condiie, respectiv care conin o anumit valoare);
Obinerea sumei unui set de rnduri dintr-un tabel;
Determinarea valorii maxime, minime i medii din coloana unui tabel (fie pentru toate
rndurile, fie numai pentru anumite rnduri).
SQL pune la dispoziie un set de cinci funcii agregat, care sunt enumerate n tabelul 6.1.
Aceste funcii v permit s efectuai toate tipurile de operaii de regsire prezentate anterior.
Funcii agregat Funcii care lucreaz cu un set de rnduri pentru a calcula i returna o
singur valoare.
Tabelul 6.1 Funciile agregat ale limbajului SQL
Funcie

Descriere

AVG()

Returneaz media valorilor dintr-o coloan

COUNT()

Returneaz numrul rndurilor dintr-o coloan

MAX()

Returneaz valoarea maxim dintr-o coloan

MIN()

Returneaz valoarea minim dintr-o coloan

SUM()

Returneaz suma valorilor incluse ntr-o coloan

Funcia AVG()
Funcia AVG() este utilizat pentru calculul mediei valorilor dintr-o anumit coloan, prin
numrarea rndurilor din tabel i nsumarea valorilor acestora. Funcia AVG() se poate utiliza
pentru calculul mediei tuturor coloanelor, respectiv a anumitor coloane sau rnduri.
Primul exemplu folosete funcia AVG() pentru a calcula preul mediu al tuturor produselor
din tabelul Produse:
SELECT AVG(pret_produs) AS pret_mediu
FROM Produse;

Instruciunea SELECT prezentat mai sus returneaz o singur valoare, i anume


pret_mediu, care conine media preurilor tuturor produselor din tabelul Produse.
Funcia AVG() se mai poate utiliza i pentru determinarea mediei valorilor din anumite
coloane sau rnduri. n exemplul urmtor se determin preul mediu al produselor oferite de un
anumit fabricant:
1

SELECT AVG(pret_produs) AS pret_mediu


FROM Produse
WHERE id_producator = 'DLL01';

Aceast instruciune SELECT difer de cea precedent numai prin faptul c instruciunea
curent conine o clauz WHERE. Clauza filtreaz numai produsele al cror identificator de
productor (id_producator) are valoarea 'DLL01'.

Funcia COUNT()
Folosind funcia COUNT(), putei determina numrul de rnduri dintr-un tabel sau numrul
de rnduri care satisfac un anumit criteriu.
Funcia COUNT() se poate folosi n dou moduri:
Formatul COUNT(*) se utilizeaz la numrarea rndurilor dintr-un tabel, indiferent dac
coloanele conin valori sau nu (valori NULL);
Formatul COUNT(coloana) se utilizeaz la numrarea rndurilor care conin valori dintr-o
anumit coloan, ignornd valorile NULL.
Acest prim exemplu determin numrul total de clieni din tabelul Clienti:
SELECT COUNT(*) AS num_clienti
FROM Clienti;

Exemplul urmtor i numr numai pe clienii care dispun de adres de e-mail:


SELECT COUNT(email_client) AS num_clienti
FROM Clienti;

Funcia MAX()
Funcia MAX() returneaz cea mai mare valoare dintr-o coloan specificat. Funcia MAX()
impune specificarea numelui coloanei, aa cum se poate vedea n continuare:
SELECT MAX(pret_produs) AS pret_maxim
FROM Produse;

Aici, funcia MAX() determin preul celui mai costisitor element din tabelul Produse.

Funcia MIN()
Funcia MIN() este exact opusul funciei MAX(): returneaz valoarea cea mai mic dintr-o
coloan specificat. Ca i MAX(), funcia MIN() impune specificarea numelui coloanei, aa
cum se poate vedea n continuare:
2

SELECT MIN(pret_produs) AS pret_minim


FROM Produse;

Aici, funcia MIN() determin preul celui mai puin costisitor articol din tabelul Produse.

Funcia SUM()
Funcia SUM() este utilizat la calculul sumei (totalului) valorilor dintr-o anumit coloan.
Iat un exemplu n care vom ilustra aceasta. Tabelul ArticoleComenzi conine articolele
aezate ntr-o anumit ordine, iar la fiecare articol este asociat o cantitate. Numrul total de
articole (suma tuturor valorilor din coloana cantitate) poate fi regsit astfel:
SELECT SUM(cantitate) AS articole_comandate
FROM ArticoleComandate
WHERE numar_comanda = 20005;

Funcia SUM(cantitate) calculeaz suma tuturor cantitilor de articole dintr-o comand,


iar prin clauza WHERE se asigur c n calcul sunt incluse elementele comandate corecte.
Funcia SUM() se mai poate folosi i la totalizarea valorilor calculate. n exemplul urmtor,
valoarea total a comenzii este regsit prin nsumarea valorilor pret_unitar*cantitate
pentru fiecare articol:
SELECT SUM(pret_unitar*cantitate) AS valoare_totala
FROM ArticoleComandate
WHERE numar_comanda = 20005;

Combinarea funciilor agregat


Toate exemplele de funcii agregat folosite pn acum au implicat o singur funcie. Dar, de
fapt, instruciunile SELECT pot folosi un numr orict de mic (sau de mare) de funcii agregat,
dup necesiti. S examinm urmtorul exemplu:
exemplu
SELECT COUNT(*) AS numar_articole,
MIN(pret_produs) AS pret_minim,
MAX(pret_produs) AS pret_maxim,
AVG(pret_produs) AS pret_mediu
FROM Produse;

n acest caz, o singur instruciune SELECT execut patru calcule de sintez ntr-o singur
etap i returneaz patru valori (numrul articolelor din tabelul Produse, precum i preul
maxim, minim i mediu al acestora).

7. Gruparea datelor
Noiunea de grupare a datelor
Grupurile v permit s mprii datele n seturi logice, pentru a putea s efectuai calcule de
sintez cu fiecare grup.

Crearea grupurilor
Grupurile se creeaz cu ajutorul clauzei GROUP BY n cadrul instruciunii SELECT.
SELECT id_producator, COUNT(*) AS numar_produse
FROM Produse
GROUP BY id_producator;

Instruciunea SELECT prezentat anterior specific dou coloane, n spe


id_producator, care conine numrul de identificare al productorului unui articol, i
numar_produse, care este un cmp cu valoare calculat (creat folosind funcia COUNT(*)).
Clauza GROUP BY indic programului SGBD s sorteze datele i s le grupeze n funcie de
valorile din coloana id_producator. Aceasta determin calculul valorilor
numar_produse o dat pentru fiecare id_producator, nu pentru ntreg tabelul.
Deoarece ai folosit clauza GROUP BY, nu a trebuit s specificai ca fiecare grup s fie
evaluat i calculat. Aceste operaii au fost efectuate automat. Clauza GROUP BY indic
programului SGBD s grupeze datele i apoi s efectueze calculul de sintez pentru fiecare grup
n parte, nu pentru ntregul set de rezultate.

Filtrarea grupurilor
n afar de posibilitatea de a grupa datele folosind GROUP BY, SQL mai permite i filtrarea
grupurilor care vor fi incluse, respectiv a celor care vor fi excluse. De exemplu,
exemplu putei dori o list
a tuturor clienilor care au emis cel puin dou comenzi. Pentru a obine aceste date, trebuie s
filtrai folosind ca baz ntregul grup, nu rnduri individuale.
SQL pune la dispoziie n acest scop clauza HAVING. n timp ce WHERE filtreaz rnduri,
HAVING filtreaz grupuri.
SELECT id_client, COUNT(*) AS comenzi
FROM Comenzi
GROUP BY id_client
HAVING COUNT(*) >= 2;

Diferena dintre HAVING i WHERE WHERE filtreaz anterior gruprii datelor, n timp ce
HAVING filtreaz dup aceast operaie, ceea ce reprezint o diferen important; rndurile
4

eliminate de o clauz WHERE nu vor mai fi incluse n grup. Aceasta poate modifica valorile
calculate care, la rndul lor, pot influena grupurile filtrate, pe baza utilizrii valorilor respective
n clauza HAVING.
Pentru a ilustra mai bine acest concept, s examinm exemplul urmtor, care afieaz toi
productorii ce ofer articole la un pre de cel puin 4 lei:
SELECT id_producator, COUNT(*) AS numar_produse
FROM Produse
WHERE pret_produs >= 4
GROUP BY id_producator
HAVING COUNT(*) >= 2;

Prima linie reprezint o instruciune SELECT elementar, care folosete o funcie agregat.
Clauza WHERE filtreaz toate rndurile cu un pre al produsului (pret_unitar) egal cu
minimum 4. Datele sunt apoi grupate n funcie de identificatorul productorului
(id_producator), dup care o clauz HAVING filtreaz numai acele grupuri care conin dou
sau mai multe rnduri. n absena clauzei WHERE, ar mai fi aprut un rnd (productorul DLL01,
care vinde patru produse cu un pre mai mic dect 4), aa cum se poate vedea n continuare:
SELECT id_producator, COUNT(*) AS numar_produse
FROM Produse
GROUP BY id_producator
HAVING COUNT(*) >= 2;

Grupare i sortare
Deseori, vei descoperi c datele grupate folosind GROUP BY vor fi ntr-adevr afiate ntr-o
ordine de grup. Dar aceasta nu se ntmpl ntotdeauna i nu este o cerin obligatorie n
specificaiile SQL. Mai mult, chiar dac programul SGBD sorteaz ntotdeauna datele n funcie
de clauza GROUP BY specificat, s-ar putea ca s dorii s fie sortate ntr-un alt mod. Faptul c
grupai datele ntr-un anumit mod (pentru a obine valori de sintez specifice unui grup) nu
nseamn c dorii ca datele de ieire s fie sortate n acelai mod. Trebuie s specificai i o
clauz explicit ORDER BY, chiar dac este una i aceeai cu clauza GROUP BY.
Pentru a demonstra utilizarea ambelor clauze, s examinm un exemplu.
exemplu Instruciunea
SELECT urmtoare este asemntoare celor prezentate anterior; regsete numrul comenzii i
numrul articolelor comandate pentru toate comenzile care conin trei sau mai multe articole:
SELECT numar_comanda, COUNT(*) AS articole
FROM ArticoleComandate
GROUP BY numar_comanda
HAVING COUNT(*) >= 3;

Pentru a sorta datele de ieire n funcie de numrul articolelor comandate, tot ce avei de
fcut este s adugai o clauz ORDER BY, aa cum se poate vedea n continuare:
SELECT numar_comanda, COUNT(*) AS articole
FROM ArticoleComandate
GROUP BY numar_comanda
HAVING COUNT(*) >= 3
ORDER BY COUNT(*), numar_comanda;

n acest exemplu, clauza GROUP BY este utilizat la gruparea datelor n funcie de numrul
comenzii (coloana numar_comanda), astfel nct funcia COUNT(*) s poat determina
numrul articolelor din fiecare comand. Clauza HAVING filtreaz datele astfel nct s fie
returnate numai comenzile care conin trei sau mai multe articole. n final, datele de ieire sunt
sortate folosind clauza ORDER BY.

Ordinea clauzelor SELECT


Este momentul potrivit s trecem n revist ordinea n care trebuie specificate clauzele
instruciunii SELECT. Tabelul 7.1 enumer toate clauzele parcurse pn acum, n ordinea n care
trebuie folosite.
Tabelul 7.1 Clauzele instruciunii SELECT i succesiunea lor
Funcie

Descriere

Dac este obligatorie

SELECT

Coloanele sau expresiile care urmeaz Da


a fi returnate

FROM

Tabelul din care urmeaz a fi regsite Numai dac se selecteaz date dintr-un
datele
tabel

WHERE

Filtrare la nivel de rnd

Nu

GROUP BY

Specificaie de grup

Numai dac se calculeaz


agregat ale unui grup

HAVING

Filtrare la nivel de grup

Nu

ORDER BY

Ordine de sortare a datelor de iesire

Nu

valori

8. Lucrul cu sub-interogri
Noiunea de sub-interogare
Interogare Orice instruciune SQL. Totui, termenul este utilizat, de regul, pentru a face
referire la instruciunile SELECT.
6

SQL permite i crearea sub-interogrilor,


sub-interogrilor adic a interogrilor care sunt nglobate n alte
interogri.

Filtrarea n funcie de sub-interogare


Tabelele folosite n cadrul exemplelor sunt tabele relaionale.
S presupunem c dorii o list a tuturor clienilor care au comandat articolul RGAN01.
Pentru a obine aceasta, se urmresc etapele:
1. Se regsesc numerele tuturor comenzilor care conin articolul RGAN01.
2. Se regsesc identificatorii tuturor clienilor care au emis comenzi care se numr printre
cele returnate n etapa precedent.
3. Se regsesc informaiile despre client corespunztoare fiecrui identificator de client
returnat n etapa precedent.
Putei folosi sub-interogri pentru a combina toate cele trei interogri ntr-o singur
instruciune.
Prima instruciune SELECT regsete coloana numar_comanda pentru toate articolele
comandate cu un identificator de produs (id_produs) identic cu RGAN01. Datele de ieire
enumer cele dou comenzi care conin acest articol:
SELECT numar_comanda
FROM ArticoleComandate
WHERE id_produs = 'RGAN01';

Etapa urmtoare const din regsirea identificatorilor de client asociai comenzilor 20007 i
20008. Folosind clauza IN putei crea o instruciune SELECT aa cum se poate vedea n
continuare:
SELECT id_client
FROM Comenzi
WHERE numar_comanda IN (20007, 20008);

Acum, combinai cele dou interogri, transformnd-o pe prima (cea care a returnat numerele
comenzilor) ntr-o sub-interogare. S examinm urmtoarea instruciune SELECT:
SELECT id_client
FROM Comenzi
WHERE numar_comanda IN (SELECT numar_comanda
FROM ArticoleComandate
WHERE id_produs = 'RGAN01');

Sub-interogrile sunt ntotdeauna prelucrate pornind de la instruciunea SELECT interioar


nspre exterior. Cnd se prelucreaz instruciunea SELECT precedent, programul SGBD
execut, de fapt, dou operaii.
Pentru nceput, execut sub-interogarea:
SELECT numar_comanda FROM ArticoleComandate WHERE id_produs =
'RGAN01'
Interogarea respectiv returneaz numerele de comenzi 20007 i 20008. Apoi, aceste dou
valori sunt trimise clauzei WHERE a interogrii exterioare, n formatul cu delimitare prin virgul
impus de operatorul IN. Interogarea exterioar devine acum:
SELECT id_client FROM Comenzi WHERE numar_comanda IN (20007,
20008)
Acum avei identificatorii tuturor clienilor care au comandat articolul RGAN01. Urmtoarea
etap const din regsirea informaiilor specifice fiecruia dintre aceti identificatori.
Instruciunea SQL de regsire a celor dou rnduri este:
SELECT nume_client, contact_client
FROM Clienti
WHERE id_client IN ('1000000004', '1000000005');
n loc de a scrie n mod explicit aceti identificatori de client, putei transforma aceast
clauz WHERE ntr-o sub-interogare:
SELECT nume_client, contact_client
FROM Clienti
WHERE id_client IN (SELECT id_client
FROM Comenzi
WHERE numar_comanda IN (SELECT numar_comanda
FROM ArticoleComandate
WHERE id_produs = 'RGAN01'));

Pentru a executa instruciunea SELECT anterioar, programul SGBD a trebuit s execute trei
instruciuni SELECT. Sub-interogarea interioar a returnat o list cu numerele comenzilor, care
au fost apoi utilizate n clauza WHERE a sub-interogrii imediat superioare. Acea sub-interogare a
returnat o list cu identificatori de client, care au fost utilizai n clauza WHERE a interogrii
principale. Aceasta din urm a returnat efectiv datele dorite.

Utilizarea sub-interogrilor sub form de cmpuri cu valoare calculat


O alt modalitate de a utiliza sub-interogrile const din crearea cmpurilor cu valoare
calculat. S presupunem c dorii s afiai numrul total de comenzi emise de fiecare client n
8

tabelul Clienti. Comenzile sunt stocate n tabelul Comenzi, alturi de identificatorul de


client corespunztor.
Pentru a executa aceast operaie, parcurgei urmtoarea succesiune de etape:
1. Regsii lista clienilor din tabelul Clienti.
2. Pentru fiecare client regsit, numrai comenzile asociate acestuia din tabelul Comenzi.
Pentru a efectua acel calcul COUNT(*) pentru fiecare client, folosii funcia COUNT(*) ca
sub-interogare.
SELECT nume_client,
stat_client,
(SELECT COUNT(*)
FROM Comenzi
WHERE Comenzi.id_client = Clienti.id_client) AS comenzi
FROM Clienti
ORDER BY nume_client;

Aceast instruciune SELECT returneaz trei coloane pentru fiecare client din tabelul
Clienti: nume_client, stat_client i comenzi. comenzi este un cmp cu valoare
calculat, care este determinat prin intermediul unei sub-interogri delimitat ntre paranteze.
Acea sub-interogare este executat cte o dat pentru fiecare client regsit. n exemplul de mai
sus, sub-interogarea este executat de cinci ori, deoarece au fost regsii cinci clieni.
Clauza WHERE din sub-interogare este puin diferit de clauzele WHERE folosite anterior,
deoarece folosete nume de coloane complet determinate. Clauza urmtoare indic programului
SQL s compare identificatorul de client din tabelul Comenzi cu acela regsit din tabelul
Clienti:
WHERE Comenzi.id_client = Clienti.id_client
Aceast sintax numele tabelului i numele coloanei, separate printr-un punct trebuie
utilizat ori de cte ori exist posibilitatea unei neclariti n ceea ce privete numele coloanelor.
n acest exemplu, exist dou coloane numite id_client: una n tabelul Clienti i alta n
tabelul Comenzi.

9. Unirea tabelelor
Noiunea de uniune
Una dintre cele mai puternice funcionaliti ale limbajului SQL o reprezint capacitatea de
unire instantanee a tabelelor n cadrul interogrilor de regsire a datelor. Uniunile se numr
printre cele mai importante operaii pe care le putei efectua folosind instruciunea SQL
SELECT, iar o bun cunoatere a uniunilor i a sintaxei acestei operaii reprezint o component
extrem de important a nvrii limbajului SQL.
9

Noiunea de tabel relaional


Apariiile multiple ale acelorai informaii nu sunt niciodat benefice, principiu care
reprezint baza proiectrii bazelor de date relaionale. Tabelele relaionale sunt proiectate astfel
nct informaiile s fie diseminate n mai multe tabele, cte unul pentru fiecare tip de date.
Tabelele sunt corelate ntre ele prin intermediul unor valori comune (de aici cuvantul relaional).
relaional
n exemplul nostru, putei crea dou tabele, unul cu informaii despre productor i altul cu
informaii despre produs. Tabelul Producatori conine toate informaiile despre productor,
cte un rnd din tabel pentru fiecare productor, alturi de un identificator unic al fiecruia.
Aceast valoare, numit cheie primar,
primar poate fi un identificator de productor sau orice alt
valoare unic.
Tabelul Produse stocheaz numai informaii despre produse i nu conine nici un fel de
date caracteristice productorului, cu excepia identificatorului acestuia (cheia primar a
tabelului Producatori). Aceast cheie stabilete legtura dintre tabelul Producatori i
tabelul Produse, iar utilizarea acestui identificator de productor permite utilizarea tabelului
Producatori pentru gsirea detaliilor referitoare la productorul corespunztor.
Datele relaionale pot fi stocate eficient i manipulate cu uurin. Din acest motiv, bazele de
date relaionale scaleaz cu mult mai bine dect bazele de date non-relaionale.
A scala A fi capabil de a suporta o ncrcare crescnd fr erori. O baz de date sau aplicaie
bine proiectat se spune c scaleaz bine.
bine

De ce s folosim uniuni?
O uniune este un mecanism folosit pentru asocierea tabelelor din cadrul unei instruciuni
SELECT (de unde i numele de uniune). Folosind o sintax special, pot fi unite mai multe
tabele astfel nct s se returneze un singur set de date de ieire, iar uniunea asociaz instantaneu
rndurile corecte din fiecare tabel.

Crearea unei uniuni


Crearea unei uniuni este o operaie foarte simpl. Trebuie s specificai toate tabelele care
urmeaz a fi incluse. Precum i legturile dintre ele. S examinm exemplul urmtor:
SELECT nume_producator, nume_produs, pret_produs
FROM Producatori, Produse
WHERE Producatori.id_producator = Produse.id_producator;

Instruciunea SELECT ncepe n acelai mod ca i toate instruciunile pe care le-ai examinat
pn acum, prin specificarea coloanelor care urmeaz a fi regsite. Marea diferen, n acest caz,
const din aceea c dou dintre coloanele specificate (nume_produs i pret_produs) se
gsesc ntr-un tabel, n timp ce o alta (nume_producator) se gsete ntr-un alt tabel.

10

Tabelele sunt unite n mod corespunztor cu ajutorul unei clauze WHERE, care indic
programului SGBD s caute identitatea dintre elementele coloanei id_producator din
tabelul Producatori i elementele coloanei omonime din tabelul Produse.
Vei observa c specificaia coloanelor este de forma Producatori.id_producator,
respectiv Produse.id_producator. Acest nume de coloan complet determinat este
obligatoriu n cazul de fa deoarece, dac specificai numai id_producator, programul
SGBD nu poate stabili la care coloan cu acest nume v referii.
Identificarea complet a numelor de coloane Trebuie s folosii numele de coloan
complet determinat (numele tabelului i numele coloanei, separate printr-un punct) ori de cte ori
exist o potenial ambiguitate privind coloana la care v referii.

Importana clauzei WHERE


Cnd tabelele sunt unite ntr-o instruciune SELECT, relaia respectiv este construit
instantaneu. Cnd unii dou tabele, de fapt alctuii perechi formate din fiecare rnd al primului
tabel i fiecare rnd al celui de-al doilea tabel. Clauza WHERE acioneaz ca un filtru, pentru a
include numai acele rnduri care corespund condiiei de filtrare n acest caz, condiia de unire.
n absena clauzei WHERE, fiecare rnd din primul tabel va fi unit cu fiecare rnd din al doilea
tabel, indiferent dac ntre ele exist sau nu o relaie logic.
Produs cartezian Rezultatele returnate de o relaie ntre tabele n absena unei condiii de
unire. Numrul rndurilor regsite va fi egal cu numrul rndurilor din primul tabel, nmulit cu
numrul rndurilor din al doilea tabel.
Pentru a nelege mai bine, examinai urmtoarea instruciune SELECT i rezultatul acesteia:
SELECT nume_producator, nume_produs, pret_produs
FROM Producatori, Produse;
Produsul cartezian corespunde rareori dorinelor. Datele returnate reprezint combinaii ntre
fiecare productor i fiecare articol, inclusiv articolele cu productor greit (chiar i productori
fr nici un articol).
Uniuni ncruciate Uneori, tipul de uniune care returneaz un produs cartezian se mai
numete i uniune ncruciat.

Uniuni interioare
Uniunea pe care ai folosit-o pn acum se numete echi-uniune adic o uniune bazat pe
verificarea egalitii valorilor cuprinse n dou tabele. Aceast categorie de uniune se mai
numete i uniune interioar. De fapt, pentru aceste uniuni se poate folosi o sintax uor diferit,
n care se specific n mod explicit tipul uniunii. Urmtoarea instruciune SELECT regsete
exact aceleai date ca i n exemplul precedent:
SELECT nume_producator, nume_produs, pret_produs
FROM Producatori INNER JOIN Produse
ON Producatori.id_producator = Produse.id_producator;
Relaia dintre cele dou tabele face parte din clauza FROM specificat sub forma INNER
JOIN. Cnd folosii aceast sintax, condiia de unire este specificat folosindu-se clauza
special ON, n locul unei clauze WHERE.

Uniunea ntre mai multe tabele


SQL nu impune nici o limit n ceea ce privete numrul tabelelor care pot fi unite n cadrul
unei instruciuni SELECT. Iat un exemplu:
exemplu
11

SELECT nume_produs, nume_producator, pret_produs, cantitate


FROM ArticoleComandate, Produse, Producatori
WHERE Produse.id_producator = Producatori.id_producator
AND ArticoleComandate.id_produs = Produse.id_produs
AND numar_comanda = 20007;

Acest exemplu afieaz articolele cuprinse n comanda cu numrul 20007. Articolele din
comand sunt stocate n tabelul ArticoleComandate. Fiecare produs este sortat n funcie de
identificatorul su, care face referire la un produs din tabelul Produse. Produsele sunt legate de
productorul corespunztor, situat n tabelul Producatori, prin identificatorul productorului,
care este stocat n nregistrarea fiecrui produs. Aici, clauza FROM menioneaz cele trei tabele,
iar clauza WHERE definete ambele condiii de unire.
Sub-interogrile nu reprezint ntodeauna cea mai eficient modalitate de a afectua operaii
SELECT complexe.
n urmtorul exemplu,
exemplu returnarea datelor necesit utilizarea a trei tabele. Dar, n loc de a le
folosi n cadrul unor sub-interogri imbricate, n acest caz se folosesc dou uniuni pentru a stabili
legtura dintre tabele. Aici exist trei condiii n clauza WHERE. Primele dou creaz o legtur
ntre tabelele din uniune, iar a treia filtreaz datele pentru a se obine numai informaiile legate
de produsul RGAN01:
SELECT nume_client, contact_client
FROM Clienti, Comenzi, ArticoleComandate
WHERE Clienti.id_client = Comenzi.id_client
AND ArticoleComandate.numar_comanda = Comenzi.numar_comanda
AND

id_produs = 'RGAN01';

10. Crearea de uniuni complexe


Utilizarea alias-urilor de tabele
n afar de utilizarea alias-urilor pentru nume de coloane i cmpuri cu valoare calculat,
SQL permite folosirea alias-urilor i pentru nume de tabele. Exist dou motive principale pentru
aceasta:
Pentru scurtarea sintaxei SQL;
Pentru a permite multiple utilizri ale aceluiai tabel n cadrul unei singure instruciuni
SELECT.
12

S examinm urmtoarea instruciune SELECT:


SELECT nume_client, contact_client
FROM Clienti AS C, Comenzi AS O, ArticoleComandate AS AC
WHERE C.id_client = O.id_client
AND AC.numar_comanda = O.numar_comanda
AND id_produs = 'RGAN01';
Vei observa c toate cele trei tabele specificate n clauza FROM au alias-uri. Clienti AS
C stabilete alias-ul C pentru tabelul Clienti etc. Aceasta v permite s folosii prescurtarea C
n locul numelui complet Clienti. n exemplul prezentat, alias-urile tabelelor au fost folosite
numai n clauza WHERE, dar utilizarea alias-urilor nu este limitat numai la aceast clauz.

Utilizarea diferitelor tipuri de uniuni


Pn acum, ai folosit numai uniuni simple, cunoscute sub numele de uniuni interne sau echiuniuni.
uniuni n continuare, vom examina alte trei tipuri de uniuni: auto-uniunea, uniunea natural i
uniunea exterioar.

Auto-uniunile
S presupunem c dorii s trimitei un mesaj tuturor persoanelor de contact clieni care
lucreaz la aceeai companie ca i Jim Jones. Aceast interogare impune ca, mai nti, s se
identifice firma pentru care lucreaz Jim Jones, iar dup aceea s se determine persoanele de
contact care lucreaz n cadrul companiei respective. n continuare este prezentat o modalitate
de rezolvare a problemei:
SELECT id_client, nume_client, contact_client
FROM Clienti
WHERE nume_client = (SELECT nume_client
FROM Clienti
WHERE contact_client = 'Jim Jones');

Aceast prim soluie folosete sub-interogri. Instruciunea SELECT interioar execut o


operaie simpl de regsire, care s returneze numele companiei (coloana nume_client)
pentru care lucreaz Jim Jones. Numele respectiv este cel utilizat n clauza WHERE a interogrii
exterioare, astfel nct s fie regsite numele tuturor persoanelor care lucreaz n cadrul
companiei respective.
Acum s examinm aceeai interogare, care de data aceasta folosete o uniune:
SELECT c1.id_client, c2.nume_client, c1.contact_client
FROM Clienti AS c1, Clienti AS c2
WHERE c1.nume_client = c2.nume_client
AND c2.contact_client = 'Jim Jones';

13

Cele dou tabele necesare n aceast interogare sunt, de fapt unul i acelai tabel, motiv
pentru care tabelul Clienti apare de dou ori n clauza FROM. Dei aceast operaie este
perfect posibil, referirile la tabelul Clienti vor fi ambigue, deoarece programul SGBD nu
tie la care tabel Clienti se face referirea.
Pentru a rezolva aceast problem, se utilizeaz alias-urile. Prima apariie a tabelului
Clienti are alias-ul c1, n timp ce a doua are alias-ul c2. Acum, aceste alias-uri se pot utiliza
ca nume de tabele. Instruciunea SELECT, de exemplu, folosete prefixul c1 pentru a specifica
n mod explicit numele complet al coloanelor dorite. Dac nu s-ar fi procedat astfel, programul
SGBD ar fi returnat o eroare, deoarece exist cte dou coloane cu numele id_client,
nume_client i contact_client. Programul nu are de unde ti care este coloana dorit
(chiar dac, n realitate, este vorba de una i aceeai coloan). Clauza WHERE ncepe prin a uni
tabelele, dup care filtreaz datele n funcie de coloana contact_client din al doilea tabel,
pentru a returna numai datele dorite.

Uniuni naturale
La fiecare uniune de tabele, cel puin o coloan va aprea n mai mult de un tabel (coloanele
ce se unesc). Uniunile standard (uniunile interioare) returneaz toate datele, chiar i mai multe
apariii ale aceleiai coloane. O uniune natural elimin pur i simplu aceste apariii multiple,
astfel nct s fie returnat cte o coloan din fiecare.
O uniune natural este acea uniune n care se selecteaz numai coloanele care sunt unice.
Aceasta se realizeaz, n mod obinuit, folosind un caracter de nlocuire (SELECT *) pentru un
tabel i sub-seturi explicite ale coloanelor pentru toate celelalte tabele. n continuare, prezentm
un exemplu:
exemplu
SELECT C.*, O.numar_comanda, O.data_comanda,
AC.id_produs,AC.cantitate, AC.pret_unitar
FROM Clienti as C, Comenzi as O, ArticoleComandate AS AC
WHERE C.id_client = O.id_client
AND AC.numar_comanda = O.numar_comanda
AND id_produs = 'RGAN01';
n acest exemplu, caracterul de nlocuire se folosete numai la primul tabel. Toate celelalte
coloane sunt menionate n mod explicit, astfel nct s nu fie regsite coloane duplicate.

Uniuni exterioare
Majoritatea uniunilor stabilesc legturi ntre rndurile dintr-un tabel i rndurile dintr-un alt
tabel. Dar, uneori, se dorete includerea rndurilor care nu sunt corelate cu alte rnduri. De
exemplu,
exemplu putei folosi uniuni exterioare pentru executarea urmtoarelor operaii:
Stabilirea numrului comenzilor emise de fiecare client, inclusiv de clienii care nu au emis
nici o comand;
Enumerarea tuturor produselor, alturi de cantitile n care au fost comandate, inclusiv
produsele pe care nu le-a comandat nimeni;
Calcularea cifrei medii de vnzri, lundu-se n calcul i pe clienii care nu au emis nc nici
o comand.
14

n fiecare dintre aceste exemple, uniunea include rnduri din tabel care nu dispun de rnduri
asociate n tabelul conex. Acest tip de uniune se numete uniune exterioar.
exterioar
Urmtoarea instruciune SELECT este o uniune interioar simpl, care regsete o list a
tuturor clienilor i a comenzilor acestora:
SELECT Clienti.id_client, Comenzi.numar_comanda
FROM Clienti INNER JOIN Comenzi
ON Clienti.id_client = Comenzi.id_client;
Sintaxa unei uniuni exterioare este asemntoare. Pentru a regsi o list a tuturor clienilor,
inclusiv a acelora care nu au emis nici o comand, putei proceda astfel:
SELECT Clienti.id_client, Comenzi.numar_comanda
FROM Clienti LEFT OUTER JOIN Comenzi
ON Clienti.id_client = Comenzi.id_client;

Spre deosebire de uniunile interioare, care stabilesc legturi ntre rnduri din ambele tabele,
uniunile exterioare cuprind i rnduri care nu sunt corelate cu alte rnduri. Cnd se folosete
sintaxa OUTER JOIN trebuie s se utilizeze cuvntul-cheie RIGHT sau LEFT pentru a specifica
tabelul din care urmeaz a se include toate rndurile (RIGHT pentru tabelul din partea dreapt a
uniunii exterioare, respectiv LEFT pentru cel din stnga). n exemplul precedent se folosete
LEFT OUTER JOIN pentru a selecta toate rndurile din tabelul situat n partea stng a clauzei
FROM (tabelul Clienti). Pentru a selecta toate rndurile din tabelul situat n dreapta, vei
folosi RIGHT OUTER JOIN, aa cum se poate vedea n exemplul prezentat n continuare:
SELECT Clienti.id_client, Comenzi.numar_comanda
FROM Clienti RIGHT OUTER JOIN Comenzi
ON Clienti.id_client = Comenzi.id_client;

Utilizarea de uniuni cu funcii agregat


Funciile agregat pot fi utilizate i cu uniunile. Pentru a ilustra aceasta, s examinm un
exemplu.
exemplu Dorii s regsii o list a tuturor clienilor i a numrului comenzilor pe care le-au emis
acetia. Linia de program urmtoare folosete funcia COUNT() pentru a efectua aceast
operaie:
SELECT Clienti.id_client, COUNT(Comenzi.numar_comanda) AS
nr_cda
FROM Clienti INNER JOIN Comenzi
ON Clienti.id_client = Comenzi.id_client
GROUP BY Clienti.id_client;

15

Instruciunea SELECT folosete INNER JOIN pentru a corela tabelele Clienti i


Comenzi. Clauza GROUP BY grupeaz datele n funcie de client, iar apelarea funciei
COUNT(Comenzi.numar_comanda) numr comenzile emise de fiecare client i le
returneaz sub numele nr_cda.
Funciile agregat pot fi utilizate la fel de simplu i cu alte tipuri de uniuni. Examinai
exemplul urmtor:
SELECT Clienti.id_client, COUNT(Comenzi.numar_comanda) AS
nr_cda
FROM Clienti LEFT OUTER JOIN Comenzi
ON Clienti.id_client = Comenzi.id_client
GROUP BY Clienti.id_client;

Acest exemplu folosete o uniune exterioar la stnga pentru a include pe toi clienii, chiar i
pe cei care nu au emis nici o comand. Rezultatele l includ i pe clientul cu numrul
1000000002, de data aceasta cu 0 comenzi.

11. Combinarea interogrilor


Noiunea de interogare combinat
Majoritatea interogrilor SQL conin o singur instruciune SELECT, care returneaz date
dintr-unul sau mai multe tabele. De asemenea, SQL permite efectuarea mai multor interogri
(instruciuni SQL multiple) i returnarea rezultatelor sub forma unui singur set de rezultate ale
interogrii. Aceste interogri combinate poart numele de reuniuni sau interogri compuse.
compuse
n esen, exist dou scenarii care permit utilizarea interogrilor combinate:
Returnarea unor date structurate ntr-un mod asemntor, preluate din tabele diferite, ntr-o
singur interogare;
Aplicarea de interogri multiple asupra unui singur tabel i returnarea rezultatelor sub forma
unei singure interogri.

Crearea interogrilor combinate


Interogrile SQL se combin folosind operatorul UNION. Folosind acest operator, se pot
specifica instruciuni SELECT multiple, iar rezultatele lor pot fi combinate ntr-un singur set de
rezultate.

16

Utilizarea operatorului UNION


S examinm un exemplu. Avei nevoie de un raport care s conin toi clienii din statele
Illinois, Indiana i Michigan. De asemenea, dorii s includei toate filialele firmei Fun4All,
indiferent de statul unde se gsesc.
Crearea unei clauze UNION implic scrierea mai multor instruciuni SELECT. Mai nti, s
examinm instruciunile individuale:
SELECT nume_client, contact_client, email_client
FROM Clienti
WHERE stat_client IN ('IL', 'IN', 'MI');

SELECT nume_client, contact_client, email_client


FROM Clienti
WHERE nume_client = 'Fun4All';

Prima instruciune SELECT regsete toate rndurile cu informaii despre clieni cu sediile n
statele Illimois, Indiana i Michigan, prin includerea abrevierilor numelor acestor state n clauza
IN. Cea de-a doua instruciune SELECT folosete un test simplu de egalitate pentru a gsi toate
filialele firmei Fun4All.
Pentru a combina cele dou instruciuni, procedai astfel:
SELECT nume_client, contact_client, email_client
FROM Clienti
WHERE stat_client IN ('IL', 'IN', 'MI')
UNION
SELECT nume_client, contact_client, email_client
FROM Clienti
WHERE nume_client = 'Fun4All';

Cuvntul-cheie UNION indic programului SGBD s execute ambele instruciuni SELECT i


s combine datele de ieire ntr-un singur set de rezultate al unei interogri.

17

Includerea sau eliminarea rndurilor duplicate


Operatorul UNION elimin n mod automat toate rndurile duplicate din setul de rezultate al
interogrii. Deoarece exist o filial a firmei Fun4All n statul Indiana, rndul respectiv a fost
returnat de ambele instruciuni SELECT. La utilizarea operatorului UNION, rndul duplicat a
fost eliminat.
Aceasta reprezint comportarea prestabilit a operatorului UNION, dar o putei modifica,
dac dorii. Dac se dorete returnarea tuturor apariiilor rndurilor care satisfac criteriile de
cutare, putei folosi UNION ALL n loc de UNION.
Privii exemplul urmtor:
SELECT nume_client, contact_client, email_client
FROM Clienti
WHERE stat_client IN ('IL', 'IN', 'MI')
UNION ALL
SELECT nume_client, contact_client, email_client
FROM Clienti
WHERE nume_client = 'Fun4All';

Utiliznd operatorul UNION ALL, progarmul SGBD nu elimin duplicatele. n consecin,


exemplul precedent returneaz cinci rnduri, unul dintre ele aprnd de dou ori.

Sortarea rezultatelor unei interogri combinate


Datele de ieire ale unei instruciuni SELECT sunt sortate folosind clauza ORDER BY. Cnd
interogrile sunt combinate cu ajutorul operatorului UNION se poate folosi o singur clauz
ORDER BY, care trebuie plasat dup ultima instruciune SELECT.
n exemplul urmtor sunt sortate rezultatele returnate de operatorul UNION utilizat anterior:
SELECT nume_client, contact_client, email_client
FROM Clienti
WHERE stat_client IN ('IL', 'IN', 'MI')
UNION
SELECT nume_client, contact_client, email_client
FROM Clienti
WHERE nume_client = 'Fun4All'
ORDER BY nume_client, contact_client;

18

Acest operator UNION preia o singur clauz ORDER BY dup instruciunea SELECT final.
Dei clauza ORDER BY pare a face parte din ultima instruciune SELECT, programul SGBD o
va folosi pentru sortarea tuturor rezultatelor returnate de toate instruciunile SELECT.

12. Inserarea datelor


Noiunea de inserare a datelor
Instruciunea INSERT este utilizat pentru a aduga rnduri ntr-un tabel dintr-o baz de
date. Aceast instruciune se poate folosi n mai multe moduri:
Pentru a insera un singur rnd complet;
Pentru a insera un singur rnd parial;
Pentru a insera rezultatele unei interogri.

Inserarea de rnduri complete


Cea mai simpl modalitate de a insera date ntr-un tabel const din utilizarea sintaxei
elementare a instruciunii INSERT, care impune specificarea numelui tabelului i a valorilor care
urmeaz a fi inserate n noul rnd. Iat un exemplu n acest sens:
INSERT INTO Clienti
VALUES('1000000006',
'Toy Land',
'123 Any Street',
'New York',
'NY',
'11111',
'USA',
NULL,
NULL);
n exemplul de mai sus, se insereaz un client n tabelul Clienti. Datele care urmeaz a fi
stocate n fiecare coloan a tabelului sunt specificate n clauza VALUES, iar pentru fiecare
coloan trebuie specificat o valoare. Dac ntr-o coloan nu se gsete nici o valoare, se va
folosi valoarea NULL. Coloanele trebuie populate n ordinea n care apar n definiia tabelului.
Metoda mai sigur de a scrie instruciunea INSERT este urmtoarea:
INSERT INTO Clienti(id_client,
nume_client,
adresa_client,
oras_client,
stat_client,
19

cod_postal_client,
tara_client,
contact_client,
email_client)
VALUES('1000000006',
'Toy Land',
'123 Any Street',
'New York',
'NY',
'11111',
'USA',
NULL,
NULL);
Acest exemplu execut exact aceeai operaie ca i instruciunea INSERT precedent, dar de
data aceasta numele coloanelor sunt precizate n mod explicit ntre paranteze, dup numele
tabelului. La inserarea rndului, programul SGBD va stabili corespondena ntre fiecare element
din lista coloanelor i fiecare element din lista VALUES.
Urmtoarea instruciune INSERT populeaz toate coloanele de rnduri, dar ntr-o alt ordine.
Deoarece numele coloanelor sunt specificate, inserarea va avea efectul dorit:
INSERT INTO Clienti(id_client,
contact_client,
email_client,
nume_client,
adresa_client,
oras_client,
stat_client,
cod_postal_client,
tara_client)
VALUES('1000000006',
NULL,
NULL,
'Toy Land',
'123 Any Street',
'New York',
'NY',
'11111',
'SUA');

20

Inserarea de rnduri pariale


S examinm exemplul urmtor:
INSERT INTO Clienti(id_client,
nume_client,
adresa_client,
oras_client,
stat_client,
cod_postal_client,
tara_client)
VALUES('1000000006',
'Toy Land',
'123 Any Street',
'New York',
'NY',
'11111',
'USA');
n exemplele prezentate anterior nu au fost precizate valorile pentru dou dintre coloane, i
anume contact_client i email_client. Aceasta nseamn c nu exist nici un motiv
de a include coloanele respective n instruciunea SELECT.
Omiterea coloanelor Putei omite coloane dintr-o operaie INSERT dac definiia tabelului
o permite. Pentru aceasta, trebuie ndeplinit una din urmtoarele condiii:
Coloana este definit ca acceptnd valori NULL (adic nici o valoare);
n definiia tabelului este specificat o valoare prestabilit. Aceasta nseamn c, dac nu se
precizeaz nici o valoare, se va utiliza valoarea prestabilit.

Inserarea datelor regsite


Exist o form a instruciunii INSERT, care se poate utiliza pentru a insera ntr-un tabel
rezultatul unei instruciuni SELECT. Aceast instruciune este cunoscut sub numele de INSERT
SELECT i, aa cum i-o arat i numele, este alctuit dintr-o instruciune INSERT i o
instruciune SELECT.
n exemplul ce urmeaz, se import date dintr-un tabel numit ClientiNoi n tabelul
Clienti. Pentru a ncerca acest exemplu, mai nti creai i populai tabelul ClientiNoi.
Formatul tabelului ClientiNoi trebuie s fie acelai cu cel al tabelului Clienti. Cnd
populai tabelul ClientiNoi, fii atent s nu folosii valori ale cmpului id_client deja
utilizate n tabelul Clienti (operaia INSERT ulterioar va eua dac valorile cheilor primare
sunt duplicate).
INSERT INTO Clienti(id_client,
contact_client,
email_client,
nume_client,
21

adresa_client,
oras_client,
stat_client,
cod_postal_client,
tara_client)
SELECT id_client,
contact_client,
email_client,
nume_client,
adresa_client,
oras_client,
stat_client,
cod_postal_client,
tara_client
FROM ClientiNoi;
Dac tabelul ClientiNoi este vid, nu va fi inserat nici un rnd (i nu va fi generat nici un
mesaj de eroare, deoarece operaia rmne valabil). Dac tabelul conine date, toate datele
respective vor fi inserate n tabelul Clienti.
Instruciunea SELECT folosit ntr-o instruciune INSERT SELECT poate include o clauz
WHERE, pentru a filtra datele care urmeaz a fi inserate.

Copierea datelor dintr-un tabel n altul


Aceasta reprezint o alt form de inserare a datelor care nu folosete instruciunea INSERT.
Pentru a copia coninutul unui tabel ntr-un alt tabel nou (creat instantaneu), putei folosi
instruciunea SELECT INTO.
INSERT SELECT sau SELECT INTO O modalitate de a explica diferenele dintre
SELECT INTO i INSERT SELECT este aceea c prima export date, n timp ce a doua le
import.
Exemplul urmtor ilustreaz modul de utilizare a instruciunii SELECT INTO:
SELECT *
INTO ClientiCopie
FROM Clienti;
Aceast instruciune SELECT creeaz un tabel nou, denumit ClientiCopie, i copiaz
ntregul coninut al tabelului Clienti n acesta. Deoarece s-a utilizat instruciunea SELECT *,
fiecare coloan din tabelul Clienti va fi creat (i populat) n tabelul ClientiCopie.
Pentru a copia numai un sub-set al coloanelor disponibile, se pot specifica nume explicite de
coloane n locul caracterului de nlocuire *.

22

13. Actualizarea i tergerea datelor


Actualizarea datelor
Pentru a actualiza (modifica) datele dintr-un tabel se utilizeaz instruciunea UPDATE.
Aceast instruciune se poate folosi n dou moduri:
Pentru actualizarea anumitor rnduri ale unui tabel;
Pentru actualizarea tuturor rndurilor dintr-un tabel.
Instruciunea UPDATE este foarte uor de utilizat. Formatul fundamental al unei instruciuni
UPDATE este alctuit din trei componente:
Tabelul care urmeaz a fi actualizat;
Numele coloanelor i noile valori ale acestora;
Condiia de filtrare care determin rndurile ce urmeaz a fi actualizate.
S examinm un exemplu simplu. Acum clientul 1000000005 are o adres de e-mail, motiv
pentru care nregistrarea lui trebuie actualizat. Instruciunea urmtoare execut aceast
actualizare:
UPDATE Clienti
SET email_client = 'kim@thetoystore.com'
WHERE id_client = '1000000005';
Instruciunea UPDATE ncepe ntotdeauna cu numele tabelului supus actualizrii. n acest
exemplu, este vorba despre tabelul Clienti. Se folosete apoi comanda SET pentru a atribui
noua valoare unei coloane. Aa cum este folosit aici, clauza SET atribuie coloanei
email_client valoarea specificat:
SET email_client = 'kim@thetoystore.com'
Instruciunea UPDATE se ncheie cu o clauz WHERE care indic programului SGBD rndul
ce urmeaz a fi actualizat. n absena unei clauze WHERE, programul SGBD va actualiza toate
rndurile din tabelul Clienti cu aceast nou adres de e-mail, ceea ce nu reprezint efectul
dorit.
Utilizarea unor coloane multiple necesit o sintax uor diferit:
UPDATE Clienti
SET contact_client = 'Sam Roberts',
email_client = 'sam@toyland.com'
WHERE id_client = '1000000006';
n acest exemplu, vor fi actualizate coloanele contact_client i email_client
aferente clientului cu numrul 1000000006.
Pentru a terge o valoare dintr-o coloan, i putei atribui valoarea NULL (presupunnd c
tabelul este definit astfel nct s accepte valori NULL). Putei proceda astfel:
UPDATE Clienti
SET email_client = 'kim@thetoystore.com'
WHERE id_client = '1000000005';
23

tergerea datelor
Pentru a terge (elimina) date dintr-un tabel, se folosete instruciunea DELETE. Aceast
instruciune se poate folosi n dou moduri:
Pentru a terge anumite rnduri dintr-un tabel;
Pentru a terge toate rndurile dintr-un tabel.
Instruciunea urmtoare terge un singur rnd din tabelul Clienti:
DELETE FROM Clienti
WHERE id_client = '1000000006';
n acest exemplu, se va terge numai clientul cu numrul 1000000006. Dac s-ar fi omis
clauza WHERE, aceast instruciune ar fi ters toi clienii din tabel.
Instruciunea DELETE nu preia nume de coloane i nici caractere de nlocuire. DELETE
terge rnduri, nu coloane. Pentru a terge anumite coloane, folosii instruciunea UPDATE.

24

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