Sunteți pe pagina 1din 42

Baze de date – Curs 6

Lect.dr. Elena Băutu


Facultatea de Matematică și Informatică
Universitatea Ovidius, Constanța
Data Manipulation Language
 DML
 Formularea de interogări – Instrucțiunea SELECT
 Operaţii de JOIN extern
 Funcţii agregat
 Clauzele GROUP BY şi HAVING
 Funcţii SQL
 Interogări complexe

2 http://ebautu.disciplinele.ml 19.03.2017
Sintaxa instrucţiunii SELECT
SELECT [DISTINCT | ALL] {* |
[expresie_coloana [AS <nume_nou>]]
[,...] }
FROM <nume_tabel> [alias] [, ...]
[WHERE conditie]
[GROUP BY lista_coloane]
[HAVING conditie]
[ORDER BY exp1 [ASC/DESC] [,exp2...]]
 Convenţiile de sintaxă în acest format sunt următoarele:
 <> reprezintă o variabilă de substituţie
 | reprezintă disjuncţia (sau)
 […] reprezintă elemente opţionale
 {…|…|…} reprezintă exact un element din listă

3 http://ebautu.disciplinele.ml 19.03.2017
Exemplu de lucru

4 http://ebautu.disciplinele.ml 19.03.2017
O instanţă posibilă
LOCALITATI JUDETE
IdJudet DenJudet CodAuto Tara Resedinta
IdLocalitat DenLocalit
Judet CodPostal 2 Constanta CT 1 2
e ate

2 Constan 2 900 3 Ile de 2 4


ta France

3 Bucures 4 0 4 Bucuresti B 1 3
ti 6 Vaslui Vs 1 8
4 Paris 3 75 7 Calarasi 1
5 Satu 2 907204
Nou
8 Alsace 2 7
6 Satu 2 907217
Nou
10 Dolj 1
7 Strasbo 8 67000
urg
8 Vaslui 6 731 11 Timis 1

9 Barlad 6 730
12 Lazio 6
11 Roma 12 030

5 http://ebautu.disciplinele.ml 19.03.2017
O instanţă posibilă
PERSOANE TARI
CodAuto
IdT
DenTara PrefixTel Internati Capitala
ara
onal
Id
Pe Localit 1 Romania 40 Ro 3
DataNaste
rs Nume Prenume ateNas CNP
rii 2 Franta F 4
oa tere
na

3 Bulgaria
1 Popescu Irina 3 12345678912 01.01.198
3 0
4 Grecia
2 Popescu Madalina 9 12312312312 02.02.199
31 0
5 Spania
3 Ionescu Vrgil 2 98765432112 03.03.201
34 0
6 Italia It 11
4 Popescu Irina 11 81231231231 04.04.201
23 5
7 Canada

6 http://ebautu.disciplinele.ml 19.03.2017
Recall – INNER JOIN
 În clauza FROM, operatorul INNER JOIN între relaţii
are ca rezultat o relaţie noua, care are
 Atribute: toate atributele din relaţiile participante la join
 Înregistrări: rânduri din produsul cartezian al celor doua
tabele care coincid pe câmpurile de legătură (cheia
străină, respectiv cheia primară)
 Se observă că nu se regăsesc în rezultatul JOIN-ului
acele rânduri din produsul cartezian ce corespund
unor înregistrări (din tabela primară) ce nu au
corespondent în tabela (străină)
 Înregistrarile trebuie să aiba valori nenule pe câmpurile
implicate în INNER JOIN (ca să apară în rezultat)

7 http://ebautu.disciplinele.ml 19.03.2017
Exemplu
 Multimea judetelor si resedinta lor de judet
SELECT DenLocalitate as Res, DenJudet as Judet
FROM LOCALITATI as l INNER JOIN JUDETE as j ON Query1
j.Resedinta = l.IdLocalitate DenJudet
 Observaţi că judetele care au resedinţa null nu apar în rezultat Calarasi

SELECT DenJudent FROM JUDETE WHERE Resedinta IS NULL; Dolj

(din diagrama alăturată) Timis


Lazio

Query1
Res Judet

Constanta Constanta
Bucuresti Bucuresti
Paris Ile de France
Strasbourg Alsace
8 http://ebautu.disciplinele.ml Vaslui Vaslui 19.03.2017
JOIN EXTERN: LEFT şi RIGHT JOIN
 Operatori de JOIN extern sunt extensii ale
operaţiei de join care evită pierderea de informaţii
 Rezultatul operaţiei de LEFT, respectiv RIGHT
JOIN include rezultatul operaţiei de INNER JOIN
reunit cu mulţimea înregistrarilor din tabela din
stanga (LEFT), respectiv dreapta (RIGHT) pentru
care nu exista corespondent în cealaltă tabelă
R1 LEFT JOIN R2 on R1.a=R2.b
 Este echivalent cu
R2 RIGHT JOIN R1 on R1.a=R2.b

9 http://ebautu.disciplinele.ml 19.03.2017
Query1
Exemplu Judet Res

Calarasi
 Dorim să aflăm mulţimea judeţelor şi resedintele
lor de judet. Dar dorim sa avem in lista si Dolj
judetele pentru care nu se cunoaste resedinta
(este null). Timis
SELECT DenJudet as Judet,
Lazio
DenLocalitate as Res
FROM JUDETE as j LEFT JOIN Constanta Constanta
LOCALITATI as l ON j.Resedinta = Bucuresti Bucuresti
l.IdLocalitate Ile de France Paris
 Observaţi că apar toate judetele Alsace Strasbourg
 Pentru cele pentru care se cunoaste resedinta, este Vaslui Vaslui
afisata denumirea acesteia
 Pentru judetele pentru care nu se cunoaste resedinta,
este afisat cu null (gol)

10 http://ebautu.disciplinele.ml 19.03.2017
Exemplu
Dorim să aflăm mulţimea Query1
judeţelor şi resedintele lor de Judet Res

judet. Dar dorim sa avem in Calarasi


lista si judetele pentru care nu
Dolj
se cunoaste resedinta (câmpul
este null). Timis

Lazio
SELECT DenJudet as
Judet, DenLocalitate as Constanta Constanta
Res Bucuresti Bucuresti

FROM LOCALITATI l RIGHT Ile de France Paris

JOIN JUDETE j ON Alsace Strasbourg

j.Resedinta = Vaslui Vaslui

l.IdLocalitate

11 http://ebautu.disciplinele.ml 19.03.2017
JOIN EXTERN
 Afișați mulțimea tuturor localităților și județul din
care acestea fac parte, indiferent dacă se
cunoaște sau nu județul
SELECT *
FROM LOCALITATI LEFT JOIN JUDETE ON
LOCALITATI.Judet = JUDETE.IdJudet
 Echivalent cu
SELECT *
FROM JUDETE RIGHT JOIN LOCALITATI ON
LOCALITATI.Judet = JUDETE.IdJudet

12 http://ebautu.disciplinele.ml 19.03.2017
JOIN EXTERN
 Rezultatul operaţiei de FULL OUTER JOIN este
reuniunea mulţimilor de înregistrări din LEFT
JOIN şi RIGHT JOIN
 Atenţie: fiind operaţii cu mulţimi, sunt eliminate
duplicatele. Astfel, înregistrările din INNER JOIN
apar o singură dată în FULL OUTER JOIN.

 Nu este definit în toate SGBDurile

13 http://ebautu.disciplinele.ml 19.03.2017
Exemplu

 Afișați mulțimea tuturor localităților și județul din


care acestea fac parte, indiferent dacă se
cunoaște sau nu județul. Listați și județele pentru
care nu există înregistrată nicio localitate.
SELECT *
FROM LOCALITATI FULL OUTER JOIN JOIN
JUDETE ON
LOCALITATI.Judet = JUDETE.IdJudet

14 http://ebautu.disciplinele.ml 19.03.2017
Exemplu
 Observatie. Multe SGBD nu implementeaza
operatorul de FULL OUTER JOIN. Acesta se
implementeaza ca un UNION intre rezultatul unui
LEFT JOIN și al unui RIGHT JOIN.
SELECT *
FROM LOCALITATI LEFT JOIN JUDETE ON
LOCALITATI.Judet = JUDETE.IdJudet
UNION
SELECT *
FROM LOCALITATI RIGHT JOIN JUDETE ON
LOCALITATI.Judet = JUDETE.IdJudet;

15 http://ebautu.disciplinele.ml 19.03.2017
Exemplu
Query1
IdLocalitate DenLocalitate Judet CodPostal IdJudet DenJudet CodAuto Tara Resedinta

7 Calarasi 1

10 Dolj 1

11 Timis 1

2 Constanta 2 900 2 Constanta CT 1 2


3 Bucuresti 4 0 4 Bucuresti B 1 3
4 Paris 3 75 3 Ile de 2 4
France

5 Satu Nou 2 907204 2 Constanta CT 1 2


6 Satu Nou 2 907217 2 Constanta CT 1 2
7 Strasbourg 8 67000 8 Alsace 2 7

8 Vaslui 6 731 6 Vaslui Vs 1 8


9 Barlad 6 730 6 Vaslui Vs 1 8
11 Roma 12 030 12 Lazio 6

La inceput sunt judetele cu Resedinta null.


16 http://ebautu.disciplinele.ml
InLOCALITATI, toate inregistrarile au judetul cunoscut. 19.03.2017
Baze de date – Curs 5
Funcţii de agregare. Clauzele GROUP BY şi HAVING.

17 http://ebautu.disciplinele.ml 19.03.2017
Funcții AGREGAT
 Funcții agregat – operează asupra unui multiset de
valori ale unei coloane dintr-o relație și returnează o
valoare
 avg: average value
 min: minimum value
 max: maximum value
 sum: sum of values
 count: number of values
 Stdev, stdevp: deviația standard (eșantion/estimator al
pop)
 Var, varP: dispersia
 First, Last: preiau valori doar din primul/ultimul tuplu
rezultat al unei interogări

18 http://ebautu.disciplinele.ml 19.03.2017
Funcții AGREGAT
 Tratează înregistrările ca un grup și
calculează rezultatul la nivel de grup
 SELECT COUNT(IdTara) FROM TARI;

Query1
Expr1000
7
 SELECT COUNT(IdPersoana) FROM
PERSOANE;
Query1
Expr1000
4

19 http://ebautu.disciplinele.ml 19.03.2017
Exemple
 Aflati data de nastere cea mai mica din PERSOANE
SELECT MIN(DataNasterii) FROM PERSOANE;

Query1
Expr1000
01.01.1980

 Aflati diferenta în zile între cea mai mare şi cea mai


mică data de nastere din PERSOANE
SELECT MAX(DataNasterii) –
MIN(DataNasterii) FROM PERSOANE;
Query1
Expr1000
12877

20 http://ebautu.disciplinele.ml 19.03.2017
Exemple
 Numărul de județe din tara cu idul 2
SELECT Count(DenJudet) Query1
FROM JUDETE Expr1000
2

WHERE Tara=2;
 Numărul de judete din alte ţări decât ţara cu idul
1. Query1
SELECT Count(*) FROM JUDETE Expr1000
3
WHERE Tara <>1;
Count(*) – întoarce numarul de tuple din rezultat

21 http://ebautu.disciplinele.ml 19.03.2017
Funcții AGREGAT
 Ce semnificaţie au interogările următoare

SELECT Count(DenJudet)
FROM JUDETE ;

SELECT Count(*)
FROM LOCALITATI
WHERE Judet = 2;

SELECT Count(IdPersoana)
FROM PERSOANE
WHERE LocalitateNastere=11;

22 http://ebautu.disciplinele.ml 19.03.2017
Clauza GROUP BY
 Permite partiţionarea în „grupuri de înregistrări‟
 Ulterior, în interogările care conţin clauza GROUP BY,
funcțiile agregat lucrează la nivelul acestor grupuri

Exemplu:
 Câte judete există în fiecare tară
SELECT Count(DenJudet) as NrJudețe, Tara
FROM JUDETE Query1
GROUP BY Tara; NrJudețe Tara
 Tările pentru care nu există 6 1

 județe nu se vor afla în rezultat 2 2


1 6

 Obs. Câmpul Tara este de tip numeric.

23 http://ebautu.disciplinele.ml 19.03.2017
Clauza GROUP BY
 În clauza GROUP BY se pot găsi unul sau mai multe
atribute dintre atributele tabelelor din clauza FROM
 Acestea definesc ierarhii de partiţii
SELECT Count(IdLocalitate)
FROM (LOCALITATI as l INNER JOIN JUDETE
as j ON l.Judet=j.IdJudet) INNER JOIN
TARI t on t.IdTara=j.Tara
GROUP BY t.IdTara, j.Judet
 Se creeaza grupuri pentru fiecare judet din fiecare tara;
 se returneaza cate localităţi sunt în fiecare grup

24 http://ebautu.disciplinele.ml 19.03.2017
Clauza GROUP BY
SELECT IdLocalitate
FROM (LOCALITATI as l INNER JOIN
JUDETE as j ON l.Judet=j.IdJudet)
INNER JOIN TARI t on t.IdTara=j.Tara
GROUP BY t.IdTara, j.Judet

Ce rezultat întoarce interogarea?


Ce IdLocalitate este selectat ca „reprezentativ‟
pentru fiecare grup în parte?

25 http://ebautu.disciplinele.ml 19.03.2017
Clauza GROUP BY
 Interogare eronată
SELECT Count(DenJudet) as NrJudețe, Tara
FROM JUDETE;

REGULĂ
Atributele din clauza SELECT care nu se găsesc în funcții de agregare,
TREBUIE să se regăsească în clauza GROUP BY. Orice alt atribut care este în
SELECT, dar nu si in GROUP BY, trebuie să fie argument al unei funcţii de
agregare (în SELECT).

Interogare corectă:
SELECT Count(DenJudet) as NrJudețe, Tara
FROM JUDETE
GROUP BY Tara

26 http://ebautu.disciplinele.ml 19.03.2017
Exemplu
Interogare corectă:
SELECT Count(DenJudet) as NrJudețe,
DenTara
FROM JUDETE INNER JOIN TARI on
JUDETE.Tara = TARI.IdTara
GROUP BY DenTara;
Query1
NrJudețe DenTara
2 Franta
1 Italia
6 Romania

27 http://ebautu.disciplinele.ml 19.03.2017
Clauza HAVING
 Permite specificarea de condiţii
 Verificarea condițiilor din HAVING se realizează
DUPĂ formarea grupurilor cu clauza GROUP BY,
spre deosebire de condițiile din WHERE care se
verifică ÎNAINTE de formarea grupurilor
 HAVING – condiții la nivel de grup
 WHERE – condiții la nivel de înregistrare

 În standard se precizează că în HAVING se pot folosi


aliasuri de coloane, definite în clauza SELECT
 În WHERE nu se pot folosi aliasuri de coloane
 În MsAccess nici în HAVING nu se pot folosi aliasuri

28 http://ebautu.disciplinele.ml 19.03.2017
Exemplu
Aflaţi mulţimea ţărilor care au mai mult de 2 judeţe.
SELECT Count(DenJudet) as NrJudețe,
DenTara
FROM JUDETE INNER JOIN TARI on
JUDETE.Tara = TARI.IdTara
GROUP BY DenTara
HAVING NrJudete>2;

Query1
NrJudețe DenTara
6 Romania

29 http://ebautu.disciplinele.ml 19.03.2017
Exemplu
 Adaugam la tabela PERSOANE un câmp
numeric Salariu. Si adaugam inregistrari.
PERSOANE
LocalitateNa
IdPersoana Nume Prenume CNP DataNasterii Salariu
stere
1 Popescu Irina 3 1234567891 01.01.1980 2000
23
2 Popescu Madalina 9 1231231231 02.02.1990 3000
231
3 Ionescu Vrgil 2 9876543211 03.03.2010
234

4 Popescu Irina 11 8123123123 04.04.2015


123

6 Ionescu Simona 3 1231231241 01.01.1990 3500


241
7 Predescu Valeriu 2 3331112221 01.01.1998 4000
112
8 Negoiţă Andreea 3 4445554445 01.01.1995 1500
554
9 Anghel Ana 11 1112221313 01.01.1986 5000
131

30 http://ebautu.disciplinele.ml
10 Marcu Ana 9 4444444444 01.01.1982 19.03.2017
444
Exemplu
 Aflati salariul mediu pentru fiecare localitate (de
nastere).
SELECT Avg(Salariu), LocalitateNastere
FROM PERSOANE
GROUP BY LocalitateNastere;

Query1
SalariuMediu LocalitateNastere
4000 2
2333,33333333333 3
3000 9
5000 11

31 http://ebautu.disciplinele.ml 19.03.2017
Exemplu
 Aflati salariul mediu pentru fiecare localitate (de
nastere). Afisati si numele localităţii.
SELECT Avg(p.Salariu) , l.DenLocalitate as Loc
FROM PERSOANE p INNER JOIN LOCALITĂŢI l on
p.LocalitateNastere = l.IdLocalitate
GROUP BY LocalitateNastere;

Query1
SalMediu Loc
3000 Barlad
2333,33333333333 Bucuresti
4000 Constanta
5000 Roma

32 http://ebautu.disciplinele.ml 19.03.2017
Observaţii
 Deşi condiţiile din WHERE pot fi enunţate şi în
HAVING (nu şi reciproc), este recomandabil ca,
ori de câte ori este posibil, să se folosească şi
WHERE (evident, pentru condiţii ce nu implică
funcţii de agregare)
 Clauza WHERE este executată înainte de
partiţionarea n grupuri
 Partiţionarea se efectuează pe un set restrâns de
înregistrări
 Condiţia din HAVING se verifică doar pe rezultatele
partiţionării
 Se face astfel economie de timp şi memorie

33 http://ebautu.disciplinele.ml 19.03.2017
Tratarea valorilor NULL în funcțiile
agregat
 Funcțiile agregat ignoră tuplele cu valori null pe
atributele din funcția agregat

 Dacă colecția conține doar valori nule, atunci


 COUNT returnează 0
 Toate celelalte returnează NULL

34 http://ebautu.disciplinele.ml 19.03.2017
Exemplu
Calculaţi salariul mediu al persoanelor care au
salariu.
SELECT AVG(Salariu) FROM PERSOANE;

Este echivalenta cu
SELECT AVG(Salariu) FROM PERSOANE
WHERE salariu IS NOT NULL;
Query1
Expr1000
3166,66666666667

35 http://ebautu.disciplinele.ml 19.03.2017
Exemplu
Calculaţi cate persoane sunt in tabel.
SELECT Count(Salariu) FROM PERSOANE;
Este echivalenta cu
SELECT Count(Salariu) FROM PERSOANE
WHERE salariu IS NOT NULL;

Query1
Expr1000
6

36 http://ebautu.disciplinele.ml 19.03.2017
Exemplu
 Suma tuturor salariilor
SELECT sum(salariu)
FROM PERSOANE;
 Ignoră valorile NULL
 Rezultatul este NULL dacă nu există nici o cantitate
nenulă în PERSOANE pe salariu (adica toate
salariile sunt null)
Query1
Expr1000
19000

37 http://ebautu.disciplinele.ml 19.03.2017
Important!
 Dacă în clauza SELECT apare vreo funcţie de
agregare, atunci orice alt atribut care apare în
SELECT (fără funcţie de agregare) trebuie să se
regăsească în clauza GROUP BY
 Clauza WHERE impune condiţii ce se verifică la
nivel de înregistrare
 Clauza HAVING impune condiţii ce se verifică la
nivel de grup de înregistrări (după ce s-a executat
WHERE)

38 http://ebautu.disciplinele.ml 19.03.2017
Funcţii ce pot fi folosite în SELECT
 Funcţii pentru şiruri de caractere: Lcase, Ucase,
Ltrim, Left, …
 Funcţii matematice: Exp, Round, Sqr,…
 Funcţii pentru date calendaristice: Now, Year,
Month, Day, Hour, Minute, Weekday,
MonthName, …
 Alte funcţii …

 Sunt dependente de SGBD

39 http://ebautu.disciplinele.ml 19.03.2017
Rezumat
 Instrucțiunea SQL SELECT
 Funcții agregat
 Clauza GROUP BY
 Clauza HAVING

40 http://ebautu.disciplinele.ml 19.03.2017
Bibliografie
 “Conceptual Data Modeling and Database
Design: A Fully Algorithmic Approach. Vol. I: The
Shortest Advisable Path”, Apple Academic Press,
Apr 2, 2015
 “Database System Concepts”, Avi Silberschatz,
Henry F. Korth, S. Sudarshan, McGraw-Hill,
January 28, 2010.
 http://codex.cs.yale.edu/avi/db-book/
 https://www.techonthenet.com/access/functions/

41 http://ebautu.disciplinele.ml 19.03.2017
Vă mulţumesc!
Întrebări?

42 http://ebautu.disciplinele.ml 19.03.2017

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