Sunteți pe pagina 1din 9

Florin Radulescu - Baze de date (note de curs)

STUD

SQL - 2

MATR
---1456
1325
1645
3145
2146
3251
2215
4311
3514
1925
2101
4705

CERERI SELECT PE MAI


MULTE TABELE

F. Radulescu. Curs: Baze de date Limbajul SQL

SPEC si BURSA

 n foarte multe cazuri se dorete ca un acelai


rezultat s conin date care sunt stocate n dou sau
mai multe tabele din baza de date, ca n exemplele
urmtoare:
 Lista cu nume studeni i denumiri specializri.
Tabelele care conin aceste date sunt STUD (numele
studentului) i SPEC (denumirea specializrii).
 Numele studenilor (din tabela STUD) i tipul burselor
acestora (din tabela BURSA).
 Numele studentului, denumirea specializrii i
cuantumul bursei. n acest caz sunt implicate toate
cele trei tabele ale bazei de date de test.

TIP
PMIN PMAX SUMA
-------------------- ----- ----- ----FARA BURSA
0
399
BURSA SOCIALA
400
899
100
BURSA DE STUDIU
900 1799
150
BURSA DE MERIT
1800 2499
200
BURSA DE EXCEPTIE
2500 9999
300
3

JOIN

F. Radulescu. Curs: Baze de date Limbajul SQL

SINTAXA

Operaia care permite astfel de regsiri se


numete join (termen preluat din limba
englez) i este realizat prin intermediul unei
cereri SELECT avnd urmtoarele
caracteristici:
n clauza FROM este specificat nu doar o
singur tabel ci o list de tabele.
n clauza WHERE exist o condiie care s
coreleze liniile tabelelor din lista FROM
(condiie numit i condiie de join).
F. Radulescu. Curs: Baze de date Limbajul SQL

F. Radulescu. Curs: Baze de date Limbajul SQL

OBIECTIV

CODS NUME
DOMENIU
----- ---------- --------------11 MATEMATICA STIINTE EXACTE
21 GEOGRAFIE UMANIST
24 ISTORIE
UMANIST

F. Radulescu. Curs: Baze de date Limbajul SQL

NUME
AN GRUPA DATAN
LOC
TUTOR PUNCTAJ CODS
------- -- ------ --------- ---------- ----- ------- ---GEORGE
4 1141A 12-MAR-82 BUCURESTI
2890
11
VASILE
2 1122A 05-OCT-84 PITESTI
1456
390
11
MARIA
3 1131B 17-JUN-83 PLOIESTI
1400
11
ION
1 2112B 24-JAN-85 PLOIESTI
3251
1670
21
STANCA
4 2141A 15-MAY-82 BUCURESTI
620
21
ALEX
5 2153B 07-NOV-81 BRASOV
1570
21
ELENA
2 2122A 29-AUG-84 BUCURESTI
2146
890
21
ADRIAN
3 2431A 31-JUL-83 BUCURESTI
450
24
FLOREA
5 2452B 03-FEB-81 BRASOV
3230
24
OANA
2 2421A 20-DEC-84 BUCURESTI
4311
760
24
MARIUS
1 2412B 02-SEP-85 PITESTI
3514
310
24
VOICU
2 2421B 19-APR-84 BRASOV
4311
1290
24

SELECT [DISTINCT] lista_de_expresii


FROM lista_de_tabele
WHERE conditie_de_join
AND conditii_suplimentare
. . .
-- alte clauze: GROUP BY, HAVING, ORDER
BY

F. Radulescu. Curs: Baze de date Limbajul SQL

Florin Radulescu - Baze de date (note de curs)

OBSERVATII

OBSERVATII (2)

Atunci cnd condiia de join lipsete, fiecare


linie a unei tabele din lista FROM este
concatenat cu fiecare linie a celorlalte
tabele, obinndu-se de fapt produsul
cartezian al acestora.
Dac n condiia de join apar numai egaliti
operaia este numit i echijoin. n celelalte
cazuri avem un non-echijoin.
n lista de tabele care particip la join o
tabel poate s apar repetat. O astfel de
operaie este numit i joinul unei tabele
cu ea nsi sau self-join.

 n cazul n care o linie a unei tabele nu se coreleaz


prin condiia de join cu nici o linie din celelalte tabele
ea nu va participa la formarea rezultatului. Se poate
ns cere ca aceasta s fie luat n considerare pentru
rezultat, rezultnd aa numitul join extern (n
englez outer join).
 n versiunile anterioare sintaxa joinului n Oracle era
diferit de standardul ANSI. ncepnd cu versiunea
Oracle 9i au fost introduse n limbaj i tipurile de join
din standardul SQL:1999 (SQL-3) printre care crossjoin, join natural i mai multe variante de join

extern.

F. Radulescu. Curs: Baze de date Limbajul SQL

PRODUS CARTEZIAN

F. Radulescu. Curs: Baze de date Limbajul SQL

ECHIJOIN

Cererea:

SELECT MATR, STUD.NUME, STUD.CODS,


SPEC.NUME
FROM STUD, SPEC
WHERE STUD.CODS = SPEC.CODS AND
DOMENIU='STIINTE EXACTE

SELECT *
FROM STUD, SPEC;

va returna un rezultat avnd 12 coloane i 36


de linii formate din concatenarea fiecrei linii
din STUD cu fiecare linie din SPEC.
De asemenea, cererea:

Este marcata conditia de join. Restul conditiei


este suplimentar

SELECT DATAN, DOMENIU


FROM STUD, SPEC
WHERE LOC='BUCURESTI';

are un rezultat coninnd 15 linii


F. Radulescu. Curs: Baze de date Limbajul SQL

NON-ECHIJOIN

10

ALIAS DE TABELA

SELECT NUME, AN, TIP, SUMA


FROM STUD, BURSA
WHERE PUNCTAJ BETWEEN PMIN AND PMAX
AND CODS=11

Este marcata conditia de join

F. Radulescu. Curs: Baze de date Limbajul SQL

F. Radulescu. Curs: Baze de date Limbajul SQL

SELECT S.NUME, S.CODS, "SP


STUD".NUME, TIP
FROM STUD S, SPEC "SP STUD", BURSA
WHERE S.CODS = "SP STUD".CODS AND
S.PUNCTAJ BETWEEN PMIN AND PMAX
Aliasul trebuie sa indeplineasca anumite
conditii (Oracle):

11

F. Radulescu. Curs: Baze de date Limbajul SQL

12

Florin Radulescu - Baze de date (note de curs)

ALIAS DE TABELA (2)

ALIAS DE TABELA (3)

Nu poate fi mai lung de 30 de caractere.


n cazul n care nu ncepe cu o liter sau cnd
conine alte caractere dact litere, cifre, _, #
i $ trebuie pus ntre ghilimele (de exemplu
atunci cnd conine spaii).
n cazul unui alias ntre ghilimele,
dimensiunea maxim de 30 de caractere nu
include ghilimelele.

F. Radulescu. Curs: Baze de date Limbajul SQL

13

ALIAS DE TABELA (4)

ntre ghilimele literele mici sunt considerate


diferite de literele mari.
Nu poate fi folosit dect n cererea curent.
Sistemul nu stocheaz n baza de date sau
altundeva aceste nume alternative.
n cazul n care o tabel are asociat un alias
prin clauza FROM acesta poate i trebuie s
fie folosit pentru prefixare n toate celelalte
clauze ale cererii.
F. Radulescu. Curs: Baze de date Limbajul SQL

14

ALIAS DE TABELA (4)

 n cazul unui alias ntre ghilimele


literele mici sunt considerate diferite
de literele mari. Din aceast cauz
dac prima linie a cererii anterioare
este:

 Dac pentru o tabel a fost definit un


alias numele tabelei nu mai poate fi
folosit pentru prefixare. n cazul cererii
anterioare, prima linie nu mai poate fi
rescris astfel:

SELECT S.NUME, S.CODS, "Sp Stud".NUME,


TIP

SELECT S.NUME, STUD.CODS,"Sp Stud".NUME,


TIP

 se obine eroare
F. Radulescu. Curs: Baze de date Limbajul SQL

15

F. Radulescu. Curs: Baze de date Limbajul SQL

16

JOIN cont.

JOIN cont.

 n cazul n care condiia de join nu este complet


rezultatul va conine un produs cartezian ntre
joinurile existente i restul tabelelor.
 Exemplu: n cererea urmtoare lipsete condiia de
join care leag tabela BURSA de celelalte tabele.
SELECT S.NUME, S.CODS, "SP STUD".NUME,
TIP
FROM STUD S, SPEC "SP STUD", BURSA
WHERE S.CODS = "SP STUD".CODS;
 n acest caz rezultatul obinut este produsul
cartezian ntre BURSA i joinul lui STUD cu SPEC i
va avea 60 de linii (5 linii din BURSA * 12 linii ale
joinului STUD cu SPEC).

1. n cazul general al unui join pe N


tabele, condiia de join este compus
din N - 1 subcondiii conectate prin
AND
care
relaioneaz
ntreg
ansamblul de tabele. Altfel spus, dac
se construiete un graf al condiiei n
care nodurile sunt tabele i arcele
subcondiii de join care leag dou
tabele atunci acest graf trebuie s fie
conex.

F. Radulescu. Curs: Baze de date Limbajul SQL

17

F. Radulescu. Curs: Baze de date Limbajul SQL

18

Florin Radulescu - Baze de date (note de curs)

JOINUL UNEI TABELE CU EA


INSASI

ALT EXEMPLU
Studenti care au acelasi tutor:

Este obligatorie folosirea aliasurilor:

SELECT S1.NUME "STUDENT 1",


S2.NUME "STUDENT 2",
S2.TUTOR "TUTOR"
FROM STUD S1, STUD S2
WHERE S1.TUTOR=S2.TUTOR;

SELECT S.NUME "NUME STUD",


S.AN "AN STUD",
T.NUME "NUME TUTOR",
T.AN "AN TUTOR"
FROM STUD S, STUD T
WHERE S.TUTOR=T.MATR

F. Radulescu. Curs: Baze de date Limbajul SQL

INCORECT! Apar si cupluri cu acelasi


student
19

ALT EXEMPLU - cont

F. Radulescu. Curs: Baze de date Limbajul SQL

20

ALT EXEMPLU - cont

Alta varianta:

Varianta corecta:

SELECT S1.NUME "STUDENT 1",


S2.NUME "STUDENT 2",
S2.TUTOR "TUTOR"
FROM STUD S1, STUD S2
WHERE S1.TUTOR=S2.TUTOR

SELECT S1.NUME "STUDENT 1",


S2.NUME "STUDENT 2",
S2.TUTOR "TUTOR"
FROM STUD S1, STUD S2
WHERE S1.TUTOR=S2.TUTOR

AND S1.MATR <> S2.MATR

AND S1.MATR > S2.MATR

INCORECT! Apar ambele cupluri XY si


YX
F. Radulescu. Curs: Baze de date Limbajul SQL

21

JOIN EXTERN (Oracle)

F. Radulescu. Curs: Baze de date Limbajul SQL

22

JOIN EXTERN (Oracle)

Apar si studentii fara tutor:

Rezultat:

SELECT S.NUME "NUME STUD", S.AN "AN


STUD", T.NUME "NUME TUTOR",
T.AN "AN TUTOR"
FROM STUD S, STUD T
WHERE S.CODS = 11 AND

NUME STUD AN STUD NUME TUTOR AN TUTOR


---------- ------- ---------- -------VASILE
2 GEORGE
4
GEORGE
4
MARIA
3

S.TUTOR=T.MATR(+)

F. Radulescu. Curs: Baze de date Limbajul SQL

23

F. Radulescu. Curs: Baze de date Limbajul SQL

24

Florin Radulescu - Baze de date (note de curs)

JOIN EXTERN (Oracle)

JOIN EXTERN FARA =


Joinul extern se poate folosi i n cazul n care
condiia nu este de egalitate. Se pot folosi
operatorii <, <=, >, >= sau <>. Un exemplu
n acest sens este urmtorul: cererea
SELECT S1.NUME "STUDENT 1",
S1.PUNCTAJ "PUNCTAJ 1",
S2.NUME "STUDENT 2",
S2.PUNCTAJ "PUNCTAJ 2"
FROM STUD S1, STUD S2
WHERE S1.PUNCTAJ > S2.PUNCTAJ;

Daca schimbam plusul apar studentii


care nu sunt tutori:
SELECT S.NUME "NUME STUD", S.AN "AN
STUD", T.NUME "NUME TUTOR",
T.AN "AN TUTOR"
FROM STUD S, STUD T
WHERE S.CODS = 11 AND
S.TUTOR(+)=T.MATR

F. Radulescu. Curs: Baze de date Limbajul SQL

25

F. Radulescu. Curs: Baze de date Limbajul SQL

26

JOIN EXTERN FARA = (cont.)

OBSERVATIE

Asa apar toate perechile (66) plus inca o linie


cu studentul avand cel mai mare punctaj:
SELECT S1.NUME "STUDENT 1",
S1.PUNCTAJ "PUNCTAJ 1",
S2.NUME "STUDENT 2",
S2.PUNCTAJ "PUNCTAJ 2"
FROM STUD S1, STUD S2
WHERE S1.PUNCTAJ (+) > S2.PUNCTAJ;

Marcajul de join extern se poate folosi


i atunci cnd condiia de join este
compus, cu excepia cazului n care se
folosete sau logic (OR) sau operatorul
de incluziune IN urmat de o list care
conine mai mult de o valoare.
Joinul extern se poate folosi i n
conjuncie cu operatorii specifici SQL

F. Radulescu. Curs: Baze de date Limbajul SQL

27

JOIN EXTERN CU BETWEEN

F. Radulescu. Curs: Baze de date Limbajul SQL

28

JOIN EXTERN CU BETWEEN (2)

cereri valide:

 cereri valide:
SELECT NUME, AN, TIP, SUMA
FROM STUD, BURSA
WHERE PUNCTAJ-1000 BETWEEN PMIN(+) AND
PMAX(+)

SELECT NUME, AN, TIP, SUMA


FROM STUD, BURSA
WHERE PUNCTAJ(+)-1000 BETWEEN PMIN AND
PMAX

Rezultatul conine ase linii complete pentru


studenii cu un (PUNCTAJ-1000) care se
ncadreaz pentru un tip de burs din tabela
BURSA i dou linii pentru cele dou tipuri de
burs care nu au nici un student asociat prin
condiia de join. Aceste 2 linii conin valori
nule pe primele dou coloane.
F. Radulescu. Curs: Baze de date Limbajul SQL

29

 Rezultat: 12 linii coninnd datele studenilor i tipul


bursei corespunztoare unui punctaj egal cu
(PUNCTAJ-1000) sau valori nule dac punctajul
respectiv nu se ncadreaz n nici un tip de burs.
 Observaie: n acest caz marcajul (+) trebuie pus
att la valoarea minim ct i la valoarea maxim. n
cazul n care lipsete de la una dintre ele nu se
semnaleaz eroare dar se calculeaz joinul normal
rezultnd 6 linii i nu 12.
F. Radulescu. Curs: Baze de date Limbajul SQL

30

Florin Radulescu - Baze de date (note de curs)

JOIN EXTERN CU LIKE

REZULTAT
 NUME
CODS NUME
CODS SABLON
 ---------- ----- ---------- ----- ----- GEORGE
11 MATEMATICA
11 1%
 VASILE
11 MATEMATICA
11 1%
 MARIA
11 MATEMATICA
11 1%
 GEORGE
11 GEOGRAFIE
21 1%
 VASILE
11 GEOGRAFIE
21 1%
 MARIA
11 GEOGRAFIE
21 1%

ISTORIE
24 4%

Cerere valida:
SELECT S.NUME, S.CODS, F.NUME, F.CODS,
SUBSTR(F.CODS, 2, 1)||'%' SABLON
FROM STUD S, SPEC F
WHERE S.CODS(+) LIKE SUBSTR(F.CODS, 2,
1)||'%';

Funcia SQL SUBSTR ntoarce un subir al


primului argument - n cazul nostru subirul
care ncepe n poziia 2 i are lungime egal
cu 1.
F. Radulescu. Curs: Baze de date Limbajul SQL

31

JOIN EXTERN CU LIKE cont.


Mutnd marcajul obinem cererea:
SELECT S.NUME, S.CODS, F.NUME, F.CODS,
SUBSTR(F.CODS, 2, 1)||'%' SABLON
FROM STUD S, SPEC F
WHERE S.CODS LIKE SUBSTR(F.CODS(+), 2,
1)||'%'

Returneaz 15 linii: 6 linii pentru cei 3


studeni pentru care condiia de join obinuit
este ndeplinit plus cte o linie pentru fiecare
dintre ceilali 9 studeni care nu verific
aceast condiie, avnd valori nule pe
coloanele 3 i 4.
F. Radulescu. Curs: Baze de date Limbajul SQL

33

CROSS JOIN

32

JOINURI SQL - 3
Exista clauzele:
CROSS JOIN produs cartezian
JOIN USING coloane comune
NATURAL JOIN join natural
JOIN ON join general
OUTER JOIN ON join extern
Pe o clauza avem o singura tabela (nu se
mai pun toate in FROM)
F. Radulescu. Curs: Baze de date Limbajul SQL

34

CROSS JOIN cont.

Implementeaza produsul cartezian:

Pentru a face join cu CROSS JOIN


adaugam conditia de join in WHERE:

SELECT [DISTINCT] lista_de_expresii


FROM tabela1
CROSS JOIN tabela2;

SELECT S.NUME, DATAN, F.NUME,


DOMENIU
FROM STUD S
CROSS JOIN SPEC F
WHERE S.CODS=F.CODS;

Exemplu:
SELECT S.NUME, F.NUME
FROM STUD S
CROSS JOIN SPEC F; -- 36 de linii

F. Radulescu. Curs: Baze de date Limbajul SQL

F. Radulescu. Curs: Baze de date Limbajul SQL

35

F. Radulescu. Curs: Baze de date Limbajul SQL

36

Florin Radulescu - Baze de date (note de curs)

JOIN USING

EXEMPLU
deoarece n STUD si SPEC avem coloane cu
acelasi nume (NUME si CODS) putem face
echjoinul dupa CODS astfel:

E un echijoin dupa coloane cu acelasi


nume specificate in USING (deci nu
toate):
SELECT [DISTINCT] lista_de_expresii
FROM tabela1
JOIN tabela2 USING (nume_coloane)

F. Radulescu. Curs: Baze de date Limbajul SQL

37

EXEMPLU cont.

F. Radulescu. Curs: Baze de date Limbajul SQL

38

E un echijoin dupa toate coloane cu


acelasi nume:
SELECT [DISTINCT] lista_de_expresii
FROM tabela1
NATURAL JOIN tabela2

Exemplu fara linii rezultat, nici un student


nu are acelasi nume cu o specializare:

SELECT S.NUME, DATAN, F.NUME, DOMENIU


FROM STUD S
JOIN SPEC F USING (CODS)
WHERE LOC='BUCURESTI';

SELECT NUME, DATAN, DOMENIU


FROM STUD
NATURAL JOIN SPEC; -- echijoin dupa NUME si CODS

39

JOIN .. ON

F. Radulescu. Curs: Baze de date Limbajul SQL

40

EXEMPLU
Exemplu: cererea urmtoare efectueaz
joinul dintre STUD i SPEC dup coloana
CODS i conine i o linie suplimentar care
oprete doar liniile corespunztoare
studenilor nscui n PLOIETI.
Aceast condiie suplimentar se putea pune
i pe clauza WHERE.

Prin aceast clauz se implementeaz


un join general. Condiia de join (i
eventual i condiiile suplimentare) se
pun la ON. Sintaxa este:
SELECT [DISTINCT] lista_de_expresii
FROM tabela1
JOIN tabela2 ON (expresie_logica)

F. Radulescu. Curs: Baze de date Limbajul SQL

Dup cum se observ n lista USING numele


coloanelor dup care se efectueaz joinul nu
trebuie prefixat cu numele sau aliasul
vreuneia dintre tabele.

NATURAL JOIN

Dac se dorete afiarea acelorai date


dar doar pentru studenii nscui n
BUCURETI se va aduga condiia
suplimentar pe WHERE:

F. Radulescu. Curs: Baze de date Limbajul SQL

SELECT S.NUME, DATAN, F.NUME, DOMENIU


FROM STUD S
JOIN SPEC F USING (CODS);

SELECT S.NUME, DATAN, F.NUME, DOMENIU


FROM STUD S
JOIN SPEC F ON (S.CODS=F.CODS AND
LOC='PLOIESTI');
41

F. Radulescu. Curs: Baze de date Limbajul SQL

42

Florin Radulescu - Baze de date (note de curs)

EXEMPLU cont.

JOIN .. ON cont.

Rezultatul este:
NUME
---------MARIA
ION

DATAN
--------17-JUN-83
24-JAN-85

NUME
---------MATEMATICA
GEOGRAFIE

Cu JOIN ON se pot calcula i nonechijoinuri. Dac se dorete o list cu


date despre studeni i bursele
acestora, urmtoarea cerere va ntoarce
rezultate corecte:

DOMENIU
--------------STIINTE EXACTE
UMANIST

SELECT NUME, PUNCTAJ, TIP, SUMA


FROM STUD
JOIN BURSA ON (PUNCTAJ BETWEEN PMIN AND
PMAX)
F. Radulescu. Curs: Baze de date Limbajul SQL

43

OUTER JOIN ON

45

RIGHT

 n cazul LEFT OUTER JOIN valorile nule provin din


tabela2. De exemplu cererea:
SELECT S.NUME "NUME STUD", S.AN "AN STUD",
T.NUME "NUME TUTOR", T.AN "AN TUTOR"
FROM STUD S
LEFT OUTER JOIN STUD T
ON (S.TUTOR=T.MATR);

returneaz 12 linii i este echivalent cu:


SELECT S.NUME "NUME STUD", S.AN "AN STUD",
T.NUME "NUME TUTOR", T.AN "AN TUTOR"
FROM STUD S, STUD T
WHERE S.TUTOR=T.MATR(+) -- conditia de join extern;

F. Radulescu. Curs: Baze de date Limbajul SQL

46

FULL

 n cazul RIGHT OUTER JOIN valorile nule provin


din tabela1. Cererea:

 n cazul RIGHT OUTER JOIN valorile nule provin


din tabela1. Cererea:

SELECT S.NUME "NUME STUD", S.AN "AN STUD",


T.NUME "NUME TUTOR", T.AN "AN TUTOR"
FROM STUD S
RIGHT OUTER JOIN STUD T
ON (S.TUTOR=T.MATR);

SELECT S.NUME "NUME STUD", S.AN "AN STUD",


T.NUME "NUME TUTOR", T.AN "AN TUTOR"
FROM STUD S
RIGHT OUTER JOIN STUD T
ON (S.TUTOR=T.MATR);

returneaz 13 linii i este echivalent cu:

returneaz 13 linii i este echivalent cu:

SELECT S.NUME "NUME STUD", S.AN "AN STUD",


T.NUME "NUME TUTOR", T.AN "AN TUTOR"
FROM STUD S, STUD T
WHERE S.TUTOR(+)=T.MATR;

F. Radulescu. Curs: Baze de date Limbajul SQL

44

LEFT

n cazul joinului extern sintaxa este


urmtoarea:
SELECT [DISTINCT] lista_de_expresii
FROM tabela1
LEFT
\
RIGHT
| OUTER JOIN tabela2
FULL
/
ON (tabela1.nume_coloana1 =
tabela2.numecoloana2)
F. Radulescu. Curs: Baze de date Limbajul SQL

F. Radulescu. Curs: Baze de date Limbajul SQL

SELECT S.NUME "NUME STUD", S.AN "AN STUD",


T.NUME "NUME TUTOR", T.AN "AN TUTOR"
FROM STUD S, STUD T
WHERE S.TUTOR(+)=T.MATR;

47

F. Radulescu. Curs: Baze de date Limbajul SQL

48

Florin Radulescu - Baze de date (note de curs)

OBSERVATIE
In Oracle o condiie de tipul:

Sfarsitul capitolului

WHERE S.TUTOR(+)=T.MATR(+)
va produce eroarea: ORA-01468: a

predicate may reference only one outerjoined table.

F. Radulescu. Curs: Baze de date Limbajul SQL

49

CERERI SELECT PE MAI MULTE


TABELE

F. Radulescu. Curs: Baze de date Limbajul SQL

50

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