Documente Academic
Documente Profesional
Documente Cultură
Limbajul SQL
3.1 Caracteristici generale ale SQL
SQL (Structured Query Language) este unul dintre cele mai puternice i larg
rspndite limbaje folosite pentru definirea i accesarea bazelor de date
relaionale. SQL nu se ncadreaz n categoria limbajelor de programare, fiind un
limbaj de aplicaii, destinat bazelor de date relaionale. SQL permite consultarea
unei bazei de date, sau executarea anumitor instruciuni asupra acesteia, prin
simpla specificare a informaiilor dorite sau a comenzilor de executat, fr fi
necesar indicarea modalitii concrete sau a algoritmilor de obinere a
rezultatului. Cu alte cuvinte, SQL poate fi considerat un limbaj declarativ
(neprocedural).
Dei este perceput drept facil i poate fi nsuit cu uurin de utilizatorii bazelor
de date, SQL permite totodat soluionarea rapid a unor solicitri complexe, ceea
ce explic interesul considerabil pe care limbajul l-a suscitat n rndul
productorilor de software. SQL este suportat de diferite sisteme de gestiune a
bazelor de date (Access i SQL Server (Microsoft), DB2 i Informix (IBM),
Oracle, Sybase etc.), limbajul dispunnd de mai multe dialecte, determinate de
specificul fiecrui S.G.B.D. n acelai timp, exist i versiuni standard, care se
bucur de o recunoatere universal n domeniul bazelor de date.
n prezent, rezolvarea problemelor de compatibilitate i portabilitate a codului
SQL se bazeaz pe standardele American National Standards Institute: ANSI
SQL-89, ANSI SQL-92 i ANSI SQL-99 (cunoscut i ca ANSI SQL3);
diferenele dintre acestea se manifest n planul regulilor de sintax, al cuvintelor
rezervate, caracterelor speciale i tipurilor de date.
Pentru fiecare standard ANSI SQL sunt definite subnivele, n raport cu care se
poate aprecia gradul n care un S.G.B.D. se conformeaz standardului respectiv:
nivelul 1 (entry level) - conformitate minimal;
Limbajul SQL
LEN ( ir_de_caractere )
Returneaz lungimea unui ir de caractere.
Baze de date
LEFT ( ir_de_caractere; nr_caractere )
RIGHT ( ir_de_caractere; nr_caractere )
MID ( ir_de_caractere; start; nr_caractere )
Returneaz un anumit numr de caractere din cadrul unui
ir, de la nceputul (LEFT), sau sfritul acestuia (RIGHT),
respectiv de la o poziie indicat explicit (MID).
3
LEFT (baze de date; 4)
returneaz primele 4 caractere:
baze
Right (baze de date; 4)
returneaz ultimele 4
date
litere:
DAY (#22/12/2008#)
Returneaz 22
MONTH (#22/12/2008#)
Returneaz 12
YEAR(#22/12/2008#)
Returneaz 2008
Limbajul SQL
*
/
\
^
Mod
AB
A*B
A/B
A\B
A^B
A Mod B
Scdere
nmulire
mprire
mprire ntreag; se returneaz ctul mpririi lui A la B
Ridicare la putere (A reprezint baza, iar B, exponentul)
Se returneaz restul mpririi lui A la B
IS
IS NOT
Observaii:
- Operatorii <, >, <=, >=, Between se aplic operanzilor de tip Number, Date/Time, dar i
Text.
- n comparaiile ntre texte se folosete exclusiv criteriul alfabetic, ignorndu-se formatul
(majuscule/minuscule). Spre exemplu, comparaiile urmtoare returneaz TRUE :
abc < xyz
Abc = abc
bca > Bac
Baze de date
Evaluare
Operand B
TRUE
FALSE
TRUE
FALSE
Rezultat
TRUE
FALSE
TRUE
TRUE
Punctul (.) este utilizat ca separator ntre numele unui cmp i numele
tabelului din care acesta provine (NumeTabel.NumeCmp)
Parantezele drepte ([]) pot fi folosite pentru a ncadra nume de cmpuri sau de
tabele, devenind chiar obligatorii n cazul numelor purttoare de caractere
neacceptate, a celor exprimate prin cuvintele rezervate ale SQL ([SELECT],
[FROM] etc.), sau a numelor interspaiate ([Nume Tabel].[Nume Cmp]).
Virgula (,) este utilizat pentru delimitarea elementelor unei liste de atribute
(SELECT nume_atribut1, nume_atribut2, ...), tabele (FROM nume_tabel1,
nume_tabel2, ...), sau valori (WHERE nume_atribut IN (valoare1,
valoare2, ...)).
Valorile text sunt delimitate prin ghilimele (text), iar cele de tip dat/timp
sunt ncadrate de # (#2/2/2009#)
Limbajul SQL
Dei SQL este un limbaj cu format liber, care nu prescrie reguli de editare a codului,
acesta este mai uor de parcurs dac se folosesc anumite convenii:
De regul, fiecare clauz a unei cereri SQL se plaseaz pe cte o linie separat;
nceputul fiecrei clauze va fi aliniat cu nceputul celorlalte.
n mod concret, astfel de abloane de sintax vor fi folosite pentru definirea unor
blocuri de cerere SQL, care rspund unor necesiti informaionale concrete i a
cror implementare poate fi realizat n trei moduri distincte:
Prin ncapsularea cererilor SQL n codul-surs al unei aplicaii (Embedded
SQL);
Prin definirea unor proceduri ce conin cod SQL i care pot fi apelate de
diverse aplicaii (Modul Language);
Prin introducere direct, folosind prompterul sau interfaa grafic oferite de un
S.G.B.D. (Direct SQL).
SQL permite implementarea tuturor funcionalitilor unui S.G.B.D, legate de
definirea i manipularea coninutului unei baze de date; din aceast perspectiv,
SQL fi considerat un limbaj complet. n mod concret, cererile SQL pot fi grupate
n mai multe categorii, dintre care, cele mai importante vizeaz:
Definirea datelor - Const n descrierea i modificarea structurii bazei de
date.
Manipularea datelor - mbrac dou forme:
Consultarea datelor - Regsirea i afiarea datelor stocate n tabele,
eventual cu efectuarea unor calcule, formatri, sortri, sau alte
Baze de date
Figura 1 Modelul relaional al unui sistem informatic pentru gestiunea tranzaciilor bursiere
Limbajul SQL
(Implementare S.G.D.B. Access 2007 - TranzaciiBursiere.accdb)
Baze de date
Numele noului tabel trebuie s fie unic la nivelul bazei de date, n timp ce
numele atributelor trebuie s fie unice la nivel de tabel.
10
Limbajul SQL
Interpretare
CREATE TABLE A (
a1 INTEGER PRIMARY KEY,
a2 TEXT (30) NOT NULL,
a3 DATE DEFAULT DATE(),
a4 NUMBER NOT NULL DEFAULT 100,
a5 NUMBER,
a6 NUMBER,
CONSTRAINT chk1 CHECK (a5 > 20),
CONSTRAINT chk2 CHECK (a3 <= DATE()),
CONSTRAINT chk3 CHECK (a4 > (2 * a5)),
CONSTRAINT idx UNIQUE (a4)
);
CREATE TABLE B (
b1 INTEGER, b2 INTEGER,
a1 INTEGER,
CONSTRAINT pk PRIMARY KEY (b1, b2),
CONSTRAINT fk1 FOREIGN KEY (a1)
REFERENCES A(a1)) ;
CREATE TABLE C (
c1 INTEGER PRIMARY KEY,
b1 INTEGER, b2 INTEGER,
CONSTRAINT fk2 FOREIGN KEY (b1, b2)
REFERENCES B(b1, b2)) ;
Baze de date
11
- b2 - Data Type: Number; Field Size: Long Integer
tergerea unui tabel din baza de date se realizeaz printr-o cerere de tipul:
DROP TABLE nume_tabel ;
- Cheie primar:
ADD CONSTRAINT nume_index PRIMARY KEY (nume_atribut [, ... n])
- Cheie extern:
ADD CONSTRAINT nume_relaie FOREIGN KEY (nume_atribut [, ... n])
REFERENCES nume_tabel_printe (nume_cmp_legtur [, ... n])
i
DROP INDEX nume_index ON nume_tabel
12
Limbajul SQL
Cererile CREATE INDEX permit definirea de indeci pe mai multe cmpuri, ale
cror realizri se pot sorta ascendent (implicit) sau descendent, accelernd astfel
regsirea datelor i rezolvarea cererilor de consultare a bazei de date.
Exemple de cereri SQL care vizeaz modificarea structurii tabelelor:
Fraz SQL
Interpretare
ALTER TABLE B
ADD COLUMN b3 Date ;
ALTER TABLE B
ADD CONSTRAINT chk CHECK
(MONTH(b3) IN (1,5,12)
AND b3 < DATE()) ;
ALTER TABLE B
ADD COLUMN b4 TEXT (15)
NOT NULL DEFAULT abc ;
ALTER TABLE B
DROP CONSTRAINT chk ;
ALTER TABLE B
DROP COLUMN b4 ;
Baze de date
13
Relaiile dintre tabele sunt consecina restriciilor de tip FOREIGN KEY, definite
la nivelul tabelelor B i C (a se vedea exemplele aferente cererilor CREATE
TABLE).
Observaie: Aceast structur cu caracter generic va fi utilizat, ca surs de date,
la exemplificarea altor tipuri de cereri SQL, pe care urmeaz s le prezentm n
continuarea acestui capitol.
Pentru simplificare, structura tabelelor va fi specificat sub forma urmtoare:
A ( a1, a2, a3, a4, a5, a6 )
B ( b1, b2, a1, b3 )
C ( c1, b1, b2 )
14
Limbajul SQL
unde:
list_selecie = { * | nume_cmp [AS alias] |
[AS alias] } [, ... n]
domeniu_selecie = {[ALL | DISTINCT | DISTINCTROW]
[TOP n [PERCENT]]}
sens_sortare = {ASC | DESC}
expresie
Instruciunea SELECT:
- list_selecie Permite enumerarea atributelor i/sau expresiilor derivate
pe baza acestora, care vor fi afiate n setul de rezultate al interogrii:
- * - Vor fi returnate realizrile tuturor cmpurilor din tabelul surs.
- nume_cmp [AS alias] Vor fi returnate realizrile anumitor
cmpuri, indicate n mod explicit. La nivelul setului de rezultate
returnat, aceste cmpuri pot fi redenumite folosind pseudonime
(alias-uri).
- expresie [AS alias] Permite specificarea unor expresii derivate pe
baza cmpurilor din tabela-surs, precum i a alias-urilor aferente
coloanelor n care rezultatele acestor expresii vor fi afiate n setul de
nregistrri returnat de interogare (n absena unui alias, se atribuie
un nume implicit: Expr1, Expr2 etc.).
- domeniu_selecie Determin redimensionarea setului de nregistrri
obinut dup aplicarea clauzei WHERE, n funcie de natura specificatorului
utilizat:
- ALL Vor fi returnate toate nregistrrile;
- DISTINCTROW Vor fi reinute doar tuplurile unice n
ansamblul lor (unicitatea este evaluat la nivelul ntregii nregistrri,
Baze de date
15
16
Limbajul SQL
Secvena de pai care trebuie parcurs pentru executarea frazei SQL prezentate
mai sus este urmtoarea:
1. Clauza FROM - Se stabilete sursa de date a interogrii n acest caz, este
vizat exclusiv tabelul Societate.
2. Clauza WHERE - Se filtreaz nregistrrile, reinndu-se doar datele
privind societile din Bucureti, cu capitalul cuprins ntre 50.000 i
100.000 RON:
Denumire
Localitate
Societate
189
533
Naturalis
TransTour
Bucureti
Bucureti
...
NrAciuni
Emise
Valoare
Nominal
200.000
75.000
0,50
0,80
CapitalSocial =
( NrAciuniEmise *
ValoareNominal )
100.000
60.000
Baze de date
17
Denumire
Naturalis
TransTour
CapitalSocial
100.000
60.000
Interpretare
Sunt selectate primele 20% din nregistrrile
tabelului A, rezultatele fiind sortate cresctor,
dup a5 i descresctor, dup a2. Se vor
afia toate cmpurile din structura tabelului.
18
Limbajul SQL
1
S se returneze brokerii care s-au angajat n ultimii 3 ani, ordonai descresctor, dup data
angajrii.
SELECT * FROM Broker
WHERE YEAR(DatAngajare) > = (YEAR (DATE()) 3)
ORDER BY DatAngajare DESC ;
2
S se obin o list a clienilor persoane juridice din Iai, Braov i Arad; ordonare dup
localitile i numele clienilor.
SELECT * FROM Client
WHERE LocalitateClient IN (Iai, Braov, Arad) AND TipClient = Persoan Juridic
ORDER BY LocalitateClient, NumeClient ;
3
S se obin o list, sortat alfabetic, a localitilor de provenien a clienilor persoane fizice.
SELECT DISTINCT LocalitateClient FROM Client
WHERE TipClient = Persoan Fizic
ORDER BY LocalitateClient ;
Observaie: ntruct nu a fost selectat pentru afiare dect atributul LocalitateClient i este posibil
ca mai muli clieni persoane fizice s domicilieze n aceeai localitate, n setul de rezultate al
interogrii pot aprea nregistrri duplicate. Specificatorul DISTINCT elimin duplicatele,
determinnd afiarea fiecrei localiti o singur dat.
4
Sub aspectul numrului de aciuni emise, s se identifice primele 10 societi ale cror titluri
au o valoare nominal de cel puin 5 RON.
SELECT TOP 10 CodSocietate, Denumire
FROM Societate
WHERE ValoareNominal > = 5
ORDER BY NrAciuniEmise DESC ;
unde:
list_selecie ={AVG|COUNT|MAX|MIN|SUM({nume_cmp | expresie})
[AS alias]} [, ... n]
Baze de date
19
Etapele care trebuie parcurse pentru executarea frazei SQL sunt urmtoarele:
1. Clauza FROM Se stabilete sursa de date a interogrii n acest caz,
tabela Broker.
2. Clauza WHERE - nregistrrile sunt filtrate, reinndu-se doar brokerii
care au fost angajai anterior anului 2008 (pentru a putea calcula vechimea
medie la nivelul anului acestui an):
20
Limbajul SQL
Nume
Broker
Prenume
Broker
Popa
Rusu
Dinu
Toma
Radu
Ion
Cristian
Dan
Mircea
Dan
...
Dat
Angajare
AnAngajare =
YEAR(DatAngajare)
02.02.2001
18.09.2007
01.09.2006
11.04.2004
18.09.2004
2001
2007
2006
2004
2004
Vechime =
2008 AnAngajare
7
1
2
4
4
Interpretare
Se returneaz valoarea maxim, minim
i medie a lui a4, n condiiile n care a5
are valori nenule.
Baze de date
21
S se determine numrul clienilor persoane juridice, cu excepia celor din Bucureti, care
nc nu beneficiaz de reprezentarea unui broker.
SELECT COUNT (*)
FROM Client
WHERE TipClient = Persoan Juridic
AND LocalitateClient < > Bucureti
AND CodBroker IS NULL ;
S se calculeze valoarea nominal medie, numrul mediu i valoarea total a aciunilor emise
de societile din Bucureti, cu capitalul social mai mare de 50.000 RON.
SELECT AVG (ValoareNominal) AS ValNominalMedie,
AVG (NrAciuniEmise) AS NrMediuAciuni,
SUM (ValoareNominal * NrAciuniEmise) AS TotalValoare
FROM Societate
WHERE LocalitateSocietate = Bucureti
AND (NrAciuniEmise * ValoareNominal) > 50000 ;
unde:
list_valori_agregat = {AVG|COUNT|MAX|MIN|SUM
({nume_cmp | expresie}) [AS alias]}[, ... n]
Instruciunea SELECT Permite specificarea cmpurilor afiabile: valorileagregat, obinute prin aciunea funciilor centralizatoare, respectiv criteriile de
grupare la care acestea se aplic (atribute ale tabelului-surs i/sau expresii
derivate pe baza acestora).
Clauza FROM - Indic tabelul ce constituie sursa de date a interogrii.
Clauza WHERE - Permite specificarea de restricii asupra nregistrrilor din
tabelul surs, centralizrile efectuate prin intermediul funciilor agregat fiind
operate exclusiv asupra tuplurilor ce se conformeaz acestor restricii.
Clauza GROUP BY - Indic atributele/expresiile pe baza crora se va realiza
gruparea nregistrrilor tabelului-surs. Pentru fiecare valoare distinct a
criteriului de grupare, sau combinaie de valori distincte asociate criteriilor
22
Limbajul SQL
multiple, se formeaz grupuri de tupluri care prezint valori identice la nivelul
atributelor/expresiilor indicate drept criterii de grupare.
Clauza HAVING - Permite specificarea criteriilor de selecie a grupurilor de
nregistrri rezultate prin aplicarea clauzei GROUP BY.
Clauza ORDER BY - Furnizeaz criteriile de sortare a grupurilor de
nregistrri rezultate prin aplicarea clauzei GROUP BY.
Baze de date
23
Cod
Societate
100
300
700
200
400
600
Denumire
...
Montana
Carpai
PaniCom
Tomis
Dunrea
Flamingo
NrAciuni
Emise
Valoare
Nominal
200.000
575.000
563.000
340.000
634.000
245.000
0,50
3,00
1,65
2,50
1,75
0,75
CapitalSocial =
( NrAciuniEmise *
ValoareNominal )
100.000
1.725.000
928.950
850.000
1.109.500
183.750
COUNT (*)
3
2
24
Limbajul SQL
6. Instruciunea SELECT - Este furnizat rezultatul, sub forma unui set de
nregistrri sortat conform clauzei ORDER BY; acesta conine valorile
distincte ale atributului LocalitateSocietate (rmase n urma filtrului
HAVING), precum i numrul nregistrrilor din grupurile constituite
pentru fiecare dintre aceste valori, afiat cu alias-ul Numr societi.
LocalitateSocietate
Constana
Braov
Numr societi
3
2
Interpretare
La nivelul valorilor distincte ale atributelor
a2 i a4, se calculeaz media i suma
realizrilor pozitive ale cmpului a6.
Baze de date
25
26
Limbajul SQL
Baze de date
27
nume_tabel2
unde:
list_selecie = { * | nume_cmp [AS alias] | expresie [AS alias]} [, ... n]
domeniu_selecie = {[ALL|DISTINCT|DISTINCTROW] [TOP n [PERCENT]]}
O alternativ la compunerile interne definite pe baza operatorului INNER JOIN
este oferit de sintaxa urmtoare:
SELECT [domeniu_selecie] list_selecie
FROM nume_tabel1, nume_tabel2 [, ... n]
WHERE condiie_jonciune [AND list_criterii_selecie] ;
n acest caz, ntr-o prim faz, nregistrrile unui tabel se combin rnd pe rnd cu
toate nregistrrile din cellalt tabel (realizndu-se operaia numit produs
cartezian), relaia dintre nregistrrile celor dou tabele fiind stabilit ulterior, prin
condiia de jonciune specificat n clauza WHERE.
Observaii:
Argumentul condiie_jonciune indic maniera n care nregistrrile din
tabelele surs pot fi asociate pe baza cmpurilor de legtur:
nume_tabel1.nume_atributA1 = nume_tabel2.nume_atributA2
Argumentul list_criterii_selecie permite specificarea de filtre asupra
setului de nregistrri generat n urma jonciunii.
ntruct n seciunea curent intereseaz n mod particular aspectele legate
de compunerile de tabele, sintaxa generic de mai sus este redat ntr-o
form simplificat. Facem ns precizarea c i n cazul interogrilor cu
mai multe tabele surs se poate recurge la centralizri i/sau sortri de
date, adugndu-se, dup caz, funcii agregat, clauzele GROUP BY,
HAVING, ORDER BY.
n situaia n care tabele distincte, folosite ca surs a aceleiai interogri
conin cmpuri cu nume identice, specificarea atributelor respective se va
realiza prin indicarea tabelelor din care provin: nume_cmp.Nume_Tabel
O interogare poate avea drept surs mai mult de dou tabele: rezultatul
compunerii a dou tabele T1 i T2 poate fi compus cu T3, tabelul rezultat
28
Limbajul SQL
fiind compus mai departe cu T4 etc. Vom exemplifica, pe baza tabelelor
generice A, B, C, definite n subcapitolul 3.2:
sau:
SELECT A.a1, a2, a4, B.b1, B.b2, c1
FROM A, B, C
WHERE A.a1=B.a1 AND B.b1 = C.b1 AND B.b2 = C.b2 ;
b) Jonciune extern
Tabela Client
Baze de date
29
S se afieze codul, numele i prenumele brokerilor care reprezint clieni din Braov.
Sintaxa A:
SELECT DISTINCT Broker.CodBroker, NumeBroker, PrenumeBroker
FROM Broker INNER JOIN Client
ON Broker.CodBroker = Client.CodBroker
WHERE LocalitateClient = Braov;
Sintaxa B:
SELECT DISTINCT Broker.CodBroker, NumeBroker, PrenumeBroker FROM Broker, Client
WHERE Broker.CodBroker = Client.CodBroker
AND LocalitateClient = Braov ;
Observaie: ntruct atributul CodBroker se regsete n ambele tabele, simpla menionare a
numelui su (SELECT CodBroker ...) nu este suficient, fiind necesar s i se precizeze
proveniena - tabela Broker, sau tabela Client. ntruct exemplul de fa ilustreaz o compunere
intern, cmpul de legtur fiind chiar CodBroker (Broker.CodBroker = Client.CodBroker),
indiferent de tabelul specificat, rezultatul este acelai.
Pentru rezolvarea cerinei de mai sus, au fost definite dou fraze SQL care produc
acelai rezultat, dar care difer prin maniera de realizare a compunerii tabelelor
surs (cu sau fr operatorul JOIN). n cele ce urmeaz vom prezenta secvena de
pai necesar execuiei ambelor blocuri SQL.
Mecanismul de execuie al frazei SQL care se conformeaz sintaxei A:
1. Clauza FROM Se stabilete sursa de date a interogrii - n acest caz, este
vorba de rezultatul compunerii tabelelor Broker i Client, pe baza valorilor
identice din cmpurile de legtur (echicompunere). Drept urmare, nu vor
fi reinute nregistrrile din tabela Broker, fr corespondent n tabela
Client (brokerul cu codul 211). Tabelul rezultat conine urmtoarele
nregistrri:
Cod
Broker
189
533
533
189
Tabela Broker
Nume
Prenume
Broker
Broker
Popescu Ion
Toma
Mircea
Toma
Mircea
Popescu Ion
...
Cod
Client
100
300
500
600
...
Tabela Client
Nume
Cod
...
Client
Broker
Montana SA
189
Alpin SRL
533
MoldoTrans SA
533
Carpai SA
189
...
Localitate
Client
Braov
Braov
Iai
Braov
Tabela Broker
Nume
Prenume
Broker
Broker
Tabela Client
...
Cod
Client
...
Nume
Client
...
Cod
Broker
...
Localitate
Client
30
Limbajul SQL
189
533
189
Popescu
Toma
Popescu
Ion
Mircea
Ion
100
300
600
Montana SA
Alpin SRL
Carpai SA
189
533
189
Braov
Braov
Braov
NumeBroker
Popescu
Toma
Popescu
PrenumeBroker
Ion
Mircea
Ion
NumeBroker
Popescu
Toma
PrenumeBroker
Ion
Mircea
Tabela Broker
Nume
Prenume
Broker
Broker
...
Cod
Client
...
Tabela Client
Nume
Cod
...
Client
Broker
...
Localitate
Client
Baze de date
189
189
189
189
211
211
211
211
533
533
533
533
Popescu
Popescu
Popescu
Popescu
Aldea
Aldea
Aldea
Aldea
Toma
Toma
Toma
Toma
Ion
Ion
Ion
Ion
Marina
Marina
Marina
Marina
Mircea
Mircea
Mircea
Mircea
100
300
500
600
100
300
500
600
100
300
500
600
31
Montana SA
Alpin SRL
MoldoTrans SA
Carpai SA
Montana SA
Alpin SRL
MoldoTrans SA
Carpai SA
Montana SA
Alpin SRL
MoldoTrans SA
Carpai SA
189
533
533
189
189
533
533
189
189
533
533
189
Braov
Braov
Iai
Braov
Braov
Braov
Iai
Braov
Braov
Braov
Iai
Braov
Tabela Broker
Nume
Prenume
Broker
Broker
Popescu Ion
Popescu Ion
Toma
Mircea
...
Cod
Client
100
600
300
...
Tabela Client
Nume
Cod
...
Client
Broker
Montana SA
189
Carpai SA
189
Alpin SRL
533
...
Localitate
Client
Braov
Braov
Braov
NumeBroker
Popescu
Toma
PrenumeBroker
Ion
Mircea
Dei mai rar utilizate dect compunerile interne, jonciunile externe sunt extrem
de utile la identificarea nregistrrilor dintr-o anumit tabel, care nu au
corespondent n alte tabele. Considerm urmtoarea cerin i fraza SQL asociat
ei:
S se afieze codurile, numele i prenumele brokerilor ce nu reprezint (nc) nici un
client.
SELECT Broker.CodBroker, NumeBroker, PrenumeBroker
FROM Broker LEFT JOIN Client
ON Broker.CodBroker = Client.CodBroker
WHERE Client.CodClient IS NULL ;
32
Limbajul SQL
Tabela Broker
Nume
Prenume
Broker
Broker
Popescu Ion
Popescu Ion
Aldea
Marina
Toma
Mircea
Toma
Mircea
...
Cod
Client
100
600
300
500
...
Tabela Client
Nume
Cod
...
Client
Broker
Montana SA
189
Carpai SA
189
Alpin SRL
MoldoTrans SA
533
533
...
Localitate
Client
Braov
Braov
Braov
Iai
Fraz SQL
SELECT DISTINCT A.a1, a4, b2
FROM A INNER JOIN B ON A.a1 = B.a1
WHERE a4 >= (2 * b2)
ORDER BY b2 DESC ;
Echivalent cu:
SELECT DISTINCT A.a1, a4, b2
FROM A, B
WHERE A.a1 = B.a1 AND a4 > = (2 * b2)
ORDER BY b2 DESC ;
SELECT DISTINCT B.*
FROM B INNER JOIN C ON
(B.b1 = C.b1 AND B.b2 = C.b2)
WHERE c1 IN (B.b1, B.b2, a1) ;
Interpretare
Compunerea intern a tabelelor A i B, cu
reinerea nregistrrilor pentru care a4
reprezint cel puin dublul lui b2 i afiarea
cmpurilor a1, a4, b2. Rezultatele sunt sortate
descresctor dup b2 i sunt eliminate
duplicatele ce pot aprea la nivelul
cmpurilor afiabile (DISTINCT).
n al II-lea bloc de cerere, jonciunea intern
este obinut prin aplicarea produsului
cartezian ntre A i B i apoi a condiiei de
jonciune din clauza WHERE (A.a1 = B.a1).
Compunerea intern a tabelelor B i C, cu
reinerea nregistrrilor pentru care c1
coincide cu b1, b2, sau a1. Sunt eliminate
duplicatele ce pot aprea la nivelul atributelor
Baze de date
Echivalent cu:
SELECT DISTINCT B.*
FROM B, C
WHERE (B.b1 = C.b1 AND B.b2 = C.b2)
AND c1 IN (B.b1, B.b2, a1) ;
SELECT A.*
FROM A LEFT JOIN
(B LEFT JOIN C
ON (B.b1 = C.b1 AND B.b2 = C.b2))
ON A.a1 = B.a1
WHERE C.c1 IS NULL ;
33
Echivalent cu:
SELECT A.*
FROM C RIGHT JOIN
(B RIGHT JOIN A ON B.a1 = A.a1)
ON (C.b1 = B.b1 AND C.b2 = B.b2)
WHERE C.c1 IS NULL ;
Exemplificarea compunerilor
TranzaciiBursiere.accdb:
de
tabele,
la
nivelul
bazei
de
date
-1S se obin lista tranzaciilor de vnzare ncheiate la data curent, de ctre clienii din Iai,
Timioara i Braov.
SELECT Tranzacie.*, NumeClient
FROM Tranzacie INNER JOIN Client ON Tranzacie.CodClientVnztor = Client.CodClient
WHERE LocalitateClient IN (Iai, Timioara, Braov) AND DatTranzacie = DATE() ;
Echivalent cu:
SELECT Tranzaie.*, NumeClient
FROM Tranzacie, Client
WHERE Tranzacie.CodClientVnztor = Client.CodClient
AND LocalitateClient IN (Iai, Timioara, Braov) AND DatTranzacie = DATE() ;
-2S se identifice clienii care nu au ncheiat nicio tranzacie n calitate de cumprtori de titluri.
SELECT Client.*
FROM Tranzacie RIGHT JOIN Client ON Tranzacie.CodClientCumprtor = Client.CodClient
WHERE Tranzacie.NrTranzacie IS NULL ;
Echivalent cu:
SELECT Client.*
FROM Client LEFT JOIN Tranzacie ON Tranzacie.CodClientCumprtor = Client.CodClient
WHERE Tranzacie.NrTranzacie IS NULL ;
-3S se determine numrul total al tranzaciilor de vnzare efectuate de clienii din Iai, la data de
7 Martie 2007.
SELECT COUNT (*) AS NrTranzacii
FROM Tranzacie INNER JOIN Client ON Tranzacie.CodClientVnztor = Client.CodClient
WHERE LocalitateClient = Iai AND DatTranzacie = #7/3/2007# ;
34
Limbajul SQL
-4S se returneze lista tranzaciilor derulate n luna curent, ntre vnztori persoane fizice i
cumprtori persoane juridice.
SELECT Tranzacie.*
FROM Client AS Client1 INNER JOIN (Tranzacie INNER JOIN Client AS Client2
ON Tranzacie.CodClientCumprator = Client2.CodClient)
ON Client1.CodClient = Tranzacie.CodClientVnztor
WHERE MONTH(DatTranzacie) = MONTH(DATE())
AND YEAR(DatTranzacie) = YEAR(DATE())
AND Client1.TipClient = Persoan Fizic
AND Client2.TipClient = Persoan Juridic ;
Observaie: n acest caz, tabela Tranzacie trebuie compus de dou ori cu tabela Client, pentru a
obine att informaii privitoare la cumprtorii, ct i la vnztorii aciunilor (n cazul nostru,
aceste informaii se rezum la statutul juridic), care sunt evideniai n acelai tabel ( Client). ntr-o
astfel de situaie, ca s putem indica proveniena datelor (clientul vnztor sau cel cumprtor) am
fost nevoii s recurgem la dou nume distincte, Client1 i Client2, pentru a referi tabelul Client.
n concluzie, SQL permite utilizarea alias-urilor nu doar la nivel de cmp, ci i pentru redenumirea
tabelelor.
-5S se afieze numrul i valoarea total a cumprrilor de titluri (cu condiia ca aceast valoare
s fie de minim 100.000 RON) efectuate n anul precedent, la nivelul fiecrei localiti, cu
excepia Bucuretiului. Rezultatele vor fi ordonate descresctor, n funcie de numrul
tranzaciilor.
SELECT LocalitateClient, COUNT (*) AS NrVnzri,
SUM (NrAciuni * Valoare) AS ValoareVnzri
FROM Cotaie INNER JOIN (Tranzacie INNER JOIN Client
ON Tranzacie.CodClientCumprtor = Client.CodClient)
ON (Cotaie.DatCotaie = Tranzacie.DatTranzacie
AND Cotaie.CodSocietate = Tranzacie.CodSocietate)
WHERE LocalitateClient < > Bucureti
AND YEAR(DatTranzacie) = YEAR (DATE()) - 1
GROUP BY LocalitateClient
HAVING SUM (NrAciuni * Valoare) > = 100000
ORDER BY COUNT (*) DESC ;
Observaie: Calcularea valorii tranzaciilor impune ca pentru titlurile cumprate s se identifice
cursul de la data ncheierii tranzaciei. Drept urmare, este necesar jonciunea tabelelor Cotaie i
Tranzactie, pe baza a dou criterii de compunere:
Cotaie.DatCotaie = Tranzacie.DatTranzacie
AND Cotaie.CodSocietate = Tranzacie. CodSocietate
3.3.5 SUBINTEROGRI
O subinterogare (sau interogare imbricat), corespunde unui bloc de cerere, plasat
n interiorul unei alte fraze SQL, care valorific sub forma unor argumente,
rezultatul produs de subinterogare. Subinterogrile pot fi definite conform
urmtoarei sintaxe:
Baze de date
35
unde:
list_selecie = {*|nume_cmp[AS alias]|expresie[AS alias]}
[, ... n]
domeniu_selecie = {[ALL|DISTINCT|DISTINCTROW][TOP n [PERCENT]]}
operator_comparaie = { > | < | > = | < = | < > | = | IN | LIKE}
Observaii:
Dup cum reiese din sintaxa prezentat, o subinterogare i interogarea n
cadrul creia a fost definit pot avea la baz acelai tabel, sau surse de date
distincte. De asemenea, att interogarea principal, ct i subinterogarea, pot
necesita ca surse de date, tabele multiple (list_tabele) care, dup caz, trebuie
compuse prin jonciuni interne, sau externe.
Sintaxa prezentat aici are o form simplificat, ce poate fi extins prin
intermediul agregrilor i/sau sortrilor (GROUP BY, HAVING, ORDER BY),
att la nivelul interogrii principale, ct i al subinterogrii. n plus, este
posibil utilizarea unei suite de subinterogri, dispuse n cascad (SELECT n
SELECT n SELECT ...). Fiecare dintre aceste interogri, cu excepia blocului
de cerere plasat pe ultimul nivel de imbricare (care nu include o alt fraz
SQL), se bazeaz pe rezultatele returnate de subinterogrile pe care le
nglobeaz.
n cazul folosirii operatorului IN, rezultatul subinterogrii este n mod necesar
reprezentat de o list de valori sau, altfel spus, de un tabel mono-coloan. Toi
ceilali operatori impun ca subinterogarea s genereze ca rezultat o valoare
unic, al crei tip de date (Number, Text, Date, Logical etc.) trebuie s fie
compatibil cu tipul de date aferent celuilalt operand implicat n comparaie.
Raportndu-ne la aceast regul de sintax, putem evalua corectitudinea
urmtoarelor cereri SQL, definite pe baza tabelelor generice A i B, definite n
subcapitolul 3.2:
A ( a1, a2, a3, a4, a5, a6 )
B ( b1, b2, a1, b3 )
Fraz SQL
Interpretare
36
Limbajul SQL
SELECT * FROM A
WHERE a1 IN (SELECT a1 FROM B) ;
SELECT * FROM A
WHERE a1 IN (SELECT * FROM B) ;
SELECT * FROM A
WHERE a1 >
(SELECT MAX (a1) FROM B) ;
SELECT * FROM A
WHERE a1 > (SELECT * FROM B) ;
Interpretare
Baze de date
37
SELECT * FROM A
WHERE a1 > ALL (SELECT a1 FROM B) ;
SELECT * FROM A
WHERE a1 = ANY (SELECT a1 FROM B) ;
SELECT * FROM A
WHERE a1 < > ALL (SELECT * FROM B) ;
SELECT * FROM A
WHERE a1 = ALL (SELECT a1 FROM B) ;
SELECT * FROM A
WHERE EXISTS
(SELECT * FROM B) ;
SELECT * FROM A
WHERE EXISTS
(SELECT * FROM B
WHERE A.a1 = B.a1) ;
Echivalent cu:
SELECT * FROM A
WHERE a1 IN (SELECT a1 FROM B)
38
Limbajul SQL
Fraz SQL
SELECT *
FROM A
WHERE a4 > = 2 * (SELECT a4
FROM A
WHERE a1 = 100) ;
Interpretare
Din tabela A, sunt returnate tuplurile
pentru care valoarea cmpului a4 este cel
puin dubl fa de valoarea aceluiai
cmp, n cazul n care a1 = 100.
Cererea este corect doar dac
subinterogarea returneaz o valoare unic
(a1 este cheie primar n tabela A, prin
urmare exist cel mult o nregistrare i
implicit o singur valoare a cmpului a4,
care satisface condiia a1 = 100)
SELECT *
FROM A
WHERE a1 IN (SELECT a1 FROM B
GROUP BY a1
HAVING SUM(b2) < 1000) ;
SELECT * FROM A
WHERE a4 > ALL (SELECT a4
FROM A
WHERE a5 > 100) ;
SELECT *
FROM B
WHERE b2 = ANY (SELECT a5
FROM A
WHERE a5 IS NOT NULL) ;
SELECT A.*
FROM A
WHERE EXISTS (SELECT *
FROM B
WHERE A.a3 = B.b3) ;
pe
baza
de
date
1
S se identifice brokerii care au i-au reprezentat clienii n tranzacii de vnzare, n luna
Martie a anilor 2005, 2006 i 2008.
SELECT * FROM Broker WHERE CodBroker IN (
SELECT CodBroker FROM Client WHERE CodClient IN (
SELECT CodClientVnztor
FROM Tranzacie
WHERE Month(DatTranzacie) = 3 AND
YEAR(DatTranzacie) IN (2005, 2006, 2008)
)) ;
Echivalent cu:
Baze de date
39
40
Limbajul SQL
ON Client.LocalitateClient = Societate.LocalitateSocietate ;
5
S identifice brokerii cu vechimea maxim.
SELECT * FROM BROKER
WHERE (YEAR(DATE()) - YEAR(DatAngajare)) >=
ALL (SELECT YEAR(DATE()) - YEAR(DatAngajare)
FROM Broker) ;
Echivalent cu:
SELECT * FROM BROKER
WHERE (YEAR(DATE()) - YEAR(DatAngajare)) =
(SELECT MAX (YEAR(DATE()) - YEAR(DatAngajare))
FROM Broker) ;
6
S identifice clienii care au efectuat i vnzri i cumprri de titluri n anul 2008.
SELECT * FROM Client
WHERE EXISTS (SELECT * FROM Tranzacie
WHERE YEAR(DatTranzacie) = 2008
AND CodClientCumprtor = Client.CodClient)
AND EXISTS (SELECT * FROM Tranzacie
WHERE YEAR(DatTranzacie) = 2008
AND CodClientVnztor = Client.CodClient) ;
Echivalent cu:
SELECT DISTINCT Client.*
FROM Client INNER JOIN Tranzacie
ON Client.CodClient= Tranzacie.CodClientCumprtor
WHERE YEAR(DatTranzacie) = 2008
AND EXISTS (SELECT * FROM Tranzacie
WHERE YEAR(DatTranzacie) = 2008
AND CodClientVnztor = Client.CodClient) ;
[ALL]
Baze de date
41
unde:
Tabela Tranzacie
42
Limbajul SQL
n fraza SQL prezentat mai sus, operatorul UNION permite alipirea rezultatelor a
dou interogri distincte, dintre care, prima returneaz clienii care au vndut
titluri, iar cea de-a doua, clienii care au achiziionat aciuni. ntruct acelai client
poate participa la mai multe tranzacii, fiecare dintre aceste interogri poate
genera duplicate la nivelul cmpurilor afiabile (CodClient, TipClient,
NumeClient); mai mult, duplicatele pot rezulta i din alipirea rezultatelor produse
de cele dou cereri de selecie, deoarece este posibil ca anumii clieni s fi avut i
calitatea de vnztori i de cumprtori (nu n cadrul aceleiai tranzacii). Pentru a
combina rezultatele produse de cele dou interogri, eliminnd totodat
duplicatele, indiferent de sursa lor, s-a folosit operatorul UNION fr
specificatorul ALL, astfel nct fiecare client va fi afiat o singur dat.
n continuare sunt redate rezultatele compunerii tabelelor Client i Tranzacie,
pentru identificarea:
- Clienilor care au vndut titluri:
Client.CodClient = Tranzacie.CodClientVnztor
Tabela Client
Cod
Client
100
100
300
500
TipClient
Persoan Juridic
Persoan Juridic
Persoan Fizic
Persoan Juridic
Nume
Client
Montana SA
Montana SA
Popa Ana
Bucovina SA
...
Nr
Tranzacie
556
700
777
802
Tabela Tranzacie
CodClient
CodClient
Vnztor Cumprtor
100
300
100
500
300
500
500
100
...
Cod
Client
300
500
500
100
TipClient
Persoan Fizic
Persoan Juridic
Persoan Juridic
Persoan Juridic
Nume
Client
Popa Ana
Bucovina SA
Bucovina SA
Montana SA
...
Nr
Tranzacie
556
700
777
802
Tabela Tranzacie
CodClient
CodClient
Vnztor Cumprtor
100
300
100
500
300
500
500
100
...
TipClient
NumeClient
Baze de date
300
500
100
Persoan Fizic
Persoan Juridic
Persoan Juridic
43
Popa Ana
Bucovina SA
Montana SA
Interpretare
Este obinut o list a datelor calendaristice din
cmpurile a3 i b3, fiecare valoare fiind preluat o
singur dat; datele sunt sortate descendent.
Este determinat media tuturor valorilor din cmpurile
a4 i a5. nainte de calculul propriu-zis, valorile sunt
reunite n cadrul unei coloane unice, asupra creia se
poate aplica funcia AVG.
44
Limbajul SQL
Interpretare
Folosind tabela A, se nsumeaz valorile
cmpului a4, la nivelul realizrilor distincte ale
atributului a2, returnndu-se doar sumele
cuprinse ntre dou limite specificate ca
parametrii.
Baze de date
45
46
Limbajul SQL
TRANSFORM valoare_agregat
SELECT list_selecie
FROM list_tabele
[WHERE
list_criterii_selecie_preagregare]
GROUP BY list_criterii_grupare
ORDER BY list_criterii_sortare
PIVOT {cmp_pivot | expresie_pivot} ;
Observaii:
- list_tabele indic tabela sau tabelele pe care este definit interogarea. n
mod evident, dac se recurge la mai multe tabele-surs, se impune
compunerea acestora prin jonciuni interne sau, dup caz, externe.
- O interogare crosstab se obine prin adugarea instruciunii TRANSFORM
i a clauzei PIVOT, naintea, respectiv la sfritul unei cereri tipice de
consultare a datelor, care trebuie ns s includ clauza GROUP BY. Drept
urmare, SELECT, FROM, WHERE, GROUP BY i ORDER BY au
aceeai semnificaie i se supun regulilor specifice cererilor de centralizare
a datelor prezentate pn n acest moment (a se revedea subcapitolul
3.3.3). Exist ns dou diferene semnificative:
- Dup cum se observ din sintax, interogrile crosstab nu admit
clauza HAVING, restriciile putnd fi specificate doar prin
intermediul clauzei WHERE; drept urmare, nu pot fi impuse
condiii asupra valorilor-agregat (de exemplu, SUM(nume_cmp) >
100).
- list_selecie nu poate include valori agregate, ci doar criterii de
grupare. n plus, n tabelul rezultat n urma interogrii, valorile
cmpurilor/expresiilor din list_selecie furnizeaz antetele
aferente rndurilor.
- cmp|expresie_pivot - Desemneaz un singur cmp (expresie) ale crui
realizri constituie criterii de agregare a datelor (alturi de valorile
cmpurilor i/sau expresiilor din list_criterii_grupare) i n acelai timp,
antete aferente coloanelor din tabelul generat de interogare.
- valoare_agregat = {AVG | COUNT | MAX
| MIN | SUM ({nume_cmp | expresie})}[AS
alias]
Indic un singur atribut (expresie) ale crui valori face obiectul
centralizrii, prin aplicarea unei singure funcii totalizatoare. Valorile-
Baze de date
47
Tabela Tranzacie
48
Limbajul SQL
n cazul ambelor fraze SQL, compunerea celor dou tabele, urmat de aplicarea
clauzei WHERE (eliminarea tranzaciilor care nu s-au ncheiat n 2007 sau 2008),
produce urmtorul rezultat:
Nr
Tranzacie
121
300
301
802
803
809
812
850
Tabela Tranzacie
Cod
...
Societate
222
333
111
111
333
444
444
111
Data
Tranzacie
01-08-2007
06-11-2007
06-11-2007
11-11-2008
12-11-2008
20-11-2008
25-11-2008
01-12-2008
...
Cod
Societate
222
333
111
111
333
444
444
111
Tabela Societate
Localitate
Denumire
Societate
Zodiac
Bucureti
Rustic
Timioara
Banatul
Timioara
Banatul
Timioara
Rustic
Timioara
Dunrea
Constana
Dunrea
Constana
Banatul
Timioara
...
Dei provin din acelai set de nregistrri i conin date identice, tabelele generate
de cele dou blocuri SQL se deosebesc prin maniera de prezentare a acestor date:
An
Lun LocalitateSocietate NrTranzacii
2007
8 Bucureti
1
2007
11 Timioara
2
2008
11 Constana
2
2008
11 Timioara
2
2008
12 Timioara
1
Rezultatul interogrii n variant non-CROSSTAB
An
Lun Bucureti Constana Timioara
2007
8
1
2007
11
2
2008
11
2
2
2008
12
1
Rezultatul interogrii n variant CROSSTAB
Baze de date
49
Interpretare
Pe baza tabelului A, pentru fiecare valoare
distinct a atributelor a2, a3 i a5, sunt nsumate
valorile din a6, care difer de cele din a4 i a5.
50
Limbajul SQL
unde:
Interpretare
Se adaug ntr-un nou tabel (Tabel1), nregistrrile
tabelului A, cu valori nenule n cmpul a3,
reinndu-se spre afiare cmpurile a1, a2 i expresia
a5 + a4. nregistrrile vor fi ordonate descresctor,
dup rezultatele expresiei a5 + a4.
Baze de date
51
52
Limbajul SQL
unde:
Interpretare
Se adaug o nou nregistrare n Tabel1, fr a se
furniza o valoare pentru cmpul Suma (e
considerat NULL).
Baze de date
53
54
Limbajul SQL
WHERE YEAR(DatTranzacie) = YEAR(DATE())
);
Interpretare
Sunt terse toate nregistrrile din tabela C.
DELETE * FROM A
WHERE a3 NOT BETWEEN
[Limita1] AND [Limita2] ;
DELETE * FROM A
WHERE a3 = (SELECT MIN(a3) FROM A) ;
Baze de date
55
Observaie: Tabelul Tranzacie trebuie compus de dou ori cu tabelul Client, pentru a obine att
informaii privitoare la cumprtorii, ct i la vnztorii aciunilor, care sunt evideniai n acelai
tabel. Dup cum s-a artat n subcapitolul 3.2, ntr-o astfel de situaie, vom referi tabelul Client
prin dou alias-uri distincte (C1 i C2), ca s putem indica sursa datelor (clientul vnztor, sau cel
cumprtor).
Clauza SET specific atributele ale cror valori vor fi modificate, precum i noile
valori ale acestora, indicate n mod explicit, sau ca realizri ale unui anumit cmp,
sau expresie.
Atunci cnd nregistrrile care fac obiectul actualizrii trebuie corelate cu cele din
alte surse, se recurge la clauza FROM, realiznd compunerea tabelului vizat de
cererea de modificare a datelor, cu alte tabelele, asociate acestuia.
Exemple bazate pe tabelul generic A, definit n subcapitolul 3.2:
A ( a1, a2, a3, a4, a5, a6 )
Fraz SQL
UPDATE A
SET a4 = (a4 * 3)
WHERE a4 < (SELECT AVG (a4) FROM A) ;
Interpretare
Se actualizeaz nregistrrile tabelei A, prin
triplarea valorii cmpului a4, cnd aceasta
este mai mic dect media.
UPDATE A
SET a5 = (a5 * 2), a6 = 20
WHERE a5 < a6 ;
UPDATE A
SET a6 = (a6 * 1.75)
FROM A INNER JOIN B ON A.a1=B.a1
WHERE a5 IN (50, 200, 300) ;
Fraz SQL
UPDATE Cotaie
SET Valoare = (Valoare * 1.3)
56
Limbajul SQL
curent, pentru
aciunile emise de
societile din Iai.
Pentru o societate
specificat ca
parametru, cursul de la
data curent va fi
stabilit ca medie a
cotaiilor nregistrate
de aciunile societii
respective, la nivelul
anului curent.
Baze de date
57
...]
Observaie: Eliminarea unui grup din baza de date nu determin n mod implicit
i tergerea utilizatorilor ce fac parte din grupul respectiv.
Exemple de instruciuni de control al accesului, definite pe baza de date
TranzaciiBursiere, prezentat n subcapitolul 3.1:
1
S se creeze dou grupuri, pentru gestiunea drepturilor aferente clienilor ce particip la
tranzacii, respectiv a celor aferente brokerilor. Utilizatorilor din ambele grupuri li se va acorda
dreptul de consultare a tabelei Cotaii, care este accesibil tuturor userilor din baza de date. n
plus, brokerii primesc toate drepturile asupra tabelei ce stocheaz informaiile despre clieni.
CREATE GROUP Brokeri, Clienti ;
GRANT SELECT ON Cotaii
TO PUBLIC ;
GRANT ALL PRIVILEGES ON Client
TO Brokeri ;
2
Sunt definii doi useri de tip broker (brokerA, brokerB).
CREATE USER brokerA, brokerB ;
ADD USER brokerA, brokerB
TO Brokeri ;
Observaie: Ambii utilizatori motenesc drepturile i limitrile definite la nivelul grupului Brokeri.
3
Sunt restricionate drepturile utilizatorului brokerA, prin interzicerea efecturii de actualizri,
respectiv tergeri de nregistrri din tabelul Client. Ulterior, utilizatorul este eliminat din baza de
date.
REVOKE UPDATE, DELETE
ON Client FROM brokerA ;
58
Limbajul SQL
Baze de date
59
60
Limbajul SQL
Produsul cartezian este operaia relaionala cel mai uor de realizat n SQL
deoarece nu necesit folosirea unui anume operator. Simpla enumerare a tabelelor
n cadrul clauzei FROM, fr specificarea anumitor condiii, genereaz ca rezultat
produsul cartezian al acelor tabele (Figura 7). Condiiile care se pot aduga fie n
cadrul clauzei FROM fie n cadrul clauzei WHERE determin selecia unui set
particular de valori, constituind, de fapt, reprezentarea n SQL a compunerii
tabelelor (Figura 10).
Pentru a realiza o list ce conine toate combinaiile posibile dintre valorile din
tabelul brokerilor i a societilor care sunt tranzacionate se folosete urmtoarea
sintax SQL:
SELECT *
FROM Broker, Societate
Baze de date
61
62
Limbajul SQL
Baze de date
63
Se observ n rezultat (Figura 11) c sunt afiate toate nregistrrile din tabela
Broker crora li se asociaz clienii consiliai, iar pentru brokerii al cror cod nu
i are corespondent n tabela Client se asociaz valoarea NULL.
64
Limbajul SQL
Baze de date
65
66
Limbajul SQL
Baze de date
67
68
Limbajul SQL
n primul caz, numele sunt returnate direct, fr a mai fi nevoie de
accesarea paginilor de date popriu-zise, ntruct valorile ce trebuie afiate
(NumeClient) sunt integral acoperite de index.
Execuia celei de-a doua cereri trebuie s continue cu identificarea
paginilor de date care conin nregistrrile corespunztoare valorilor
NumeClient regsite prin intermediul indexului, ntruct trebuie afiate i
realizrile celorlalte cmpuri (neindexate).
Concluzia care trebuie s se desprind din acest exemplu este c numrul
cmpurilor afiabile trebuie limitat la minimul necesar i nu c ar trebui
definii indeci pe toate cmpurile ce ar putea, la un moment dat, s fie
selectate spre afiare, ntruct beneficiile de performan pot fi contrabalansate
de costurile impuse de actualizarea i folosirea acestor indeci. n plus, n
cazul unui index care include mai multe cmpuri, este posibil ca parcurgerea
secvenial a nregistrrilor tabelului pe care indexul a fost definit s necesite
un consum de timp mai redus dect utilizarea indexului.
n cadrul unei cereri SQL, ori de cte ori este posibil, se vor prefera
compunerile de tabele n defavoarea subinterogrilor, ntruct acestea din
urm impun parcurgerea secvenial a nregistrrilor tabelului din interior
pentru fiecare rnd al tabelului exterior. Spre exemplu, cererea:
SELECT * FROM Societate
WHERE CodSocietate IN
(SELECT CodSocietate FROM Tranzacie) ;
poate fi rescris astfel:
SELECT DISTINCT Societate.*
FROM Societate INNER JOIN Tranzacie ON
Societate.CodSocietate = Tranzacie.CodSocietate ;
Observaie: Dei specificatorul DISTINCT este necesar dac dorim ca cele
dou cereri s produc rezultate similare, dup cum vom arta n cele ce
urmeaz, acesta poate afecta n mod negativ performana interogrilor.
Avnd n vedere consumul de timp necesar ca liniile din fiecare tabel s poat
fi combinate cu tuplurile din toate celelalte tabele-surs, se impune ca
interogrile ce recurg la operaii tip produs cartezian s fie bine justificate, n
caz contrar ele putnd deveni cu uurin contra-productive, mai cu seam
dac au la baz tabele de cu un volum mare de nregistrri. Atunci cnd prin
clauzele WHERE sau GROUP BY, sau prin specificatorul DISTINCT, se
urmrete limitarea setului de nregistrri returnat de o astfel de operaie, cel
mai probabil, aceasta nici nu era absolut necesar, fiind mai indicat o
jonciune intern (INNER JOIN), care reprezint totodat o opiune mult mai
avantajoas n planul performanei.
Baze de date
69
Bibliografie
1. Allison C., Berkowitz N., SQL for Microsoft Access (2nd Edition),
Wordware Publishing, 2008
2. Bagui S., Earp, R., Learning SQL: A Step-by-Step Guide Using Access,
Addison Wesley, 2003
3. Florescu V., Nstase P., Berbec F., Baze de date Fundamente teoretice i
practice, Infomega, 2002
4. Forta B., SQL n lecii de 10 minute, Teora, 2004
70
Limbajul SQL
5. Henderson K., Transact SQL, Teora, 2002
6. Kriegel A., Trukhnov, B.M., SQL Bible, Wiley Publishing, 2003
7. Nstase P., Mihai F., Coscescu L., Brbulescu B., Stanciu A., ova R.,
Covrig L., Baze de date Microsoft Access 2000, Teora, 2000
8. *** http://office.microsoft.com/ro-ro/access