Documente Academic
Documente Profesional
Documente Cultură
Modalitatea prin care, pornind de la o schemă relaţională, pot fi obţinute diverse informaţii dintr-o
bază de date se numeşte interogare (QUERY), iar formularea unei interogări înseamnă redactarea unei
fraze SELECT.
Termenul de interogare este oarecum impropriu pentru că o interogare SQL nu este neapărat o
întrebare pusă bazei de date. Ea poate fi şi o comandă pentru executarea uneia din acţiunile următoare:
- să construiască sau să şteargă o bază de date;
- să insereze, să modifice sau să şteargă linii sau câmpuri;
- să caute în câteva tabele o anumită informaţie şi să returneze rezultatele într-o anumită ordine;
- să modifice securitatea informaţiilor.
O frază SELECT are un format simplu şi flexibil. Cele trei clauze principale sunt SELECT, FROM şi
WHERE dintre care doar primele două sunt obligatorii.
Sintaxa oarecum simplificată a unei interogări SQL este următoarea:
unde:
lista_atribute - specifică atributele ale căror valori vor fi returnate
În continuare este realizată o paralelă între clauzele principale ale frazei SELECT cu operatorii
algebrei relaţionale prezentaţi în capitolul 3 Algebra relaţională.
Selecţie şi proiecţie
Clauza SELECT în algebra relaţională corespunde operatorului proiecţie, ea fiind folosită pentru a
desemna care sunt coloanele care vor apărea în rezultat. Clauza FROM este folosită pentru a enumera
tabelele (relaţiile) din care vor fi extrase informaţiile aferente consultării. Prin clauza WHERE este
desemnat predicatul selectiv al algebrei relaţionale, ce se aplică atributelor din relaţiile care apar în clauza
FROM.
O consultare simplă în SQL, la modul cel mai general şi simplist, poate fi prezentată astfel:
Rezultatul unei astfel de fraze SQL se prezintă sub o formă tabelară. Această formă poate fi o listă
(text), o tabelă propriu-zisă sau o tabelă temporară, dar şi o tabelă derivată (imagine). Sunt şi cazuri în
care rezultatul poate fi obţinut şi ca o variabilă masiv (tablou).
Ci – reprezintă coloanele (care pot fi atribute sau expresii de atribute) rezultat;
Tj – tabelele ce trebuie parcurse pentru obţinerea rezultatului;
P – predicatul (condiţia) simplu sau compus ce trebuie îndeplinit de tupluri pentru a putea fi incluse
în rezultat.
Atunci când clauza WHERE nu este prezentă, se consideră în mod implicit că valoarea logică a
predicatului P este „adevărat” şi în consecinţă, toate liniile din tabela sau produsul cartezian al tabelelor
specificată/specificate în clauza FROM vor fi incluse în rezultat.
Dacă în locul coloanelor C1, C2, ..., Cn, apare simbolul * (asterisc), rezultatul va fi format din toate
atributele tabelelor specificate în clauza FROM. De asemenea, numele atributelor rezultatului sunt
numele atributelor din tabela (tabelele) specificată în FROM. Dacă se doreşte schimbarea acestui nume
rezultat se apelează la clauza AS.
Conform restricţiei de unicitate, într-o relaţie nu pot exista două linii identice. În schimb, în SQL,
tabela obţinută dintr-o consultare poate conţine două sau mai multe tupluri identice.
Spre deosebire de algebra relaţională, unde tuplurile identice (dublurile) sunt eliminate automat din
rezultat, în SQL nu se întâmplă acelaşi lucru. Pentru aceasta este necesară folosirea opţiunii DISTINCT.
Din cele prezentate până acum se poate trage concluzia că o frază SELECT corespunde:
- unei proiecţii (SELECT C1),
- unui produs cartezian (FROM R1 R2 ... Rm),
- unei selecţii algebrice (WHERE P).
şi conduce la obţinerea unui rezultat cu „n” coloane, fiecare coloană fiind un atribut din T1, T2, ..., Tm
sau expresie calculată pe baza unor atribute din T1, T2, ..., Tm.
În continuare, vom transpune în SQL, câteva dintre interogările din capitolul dedicat algebrei
relaţionale.
Exemplu:
Selecţie
SELECT *
FROM R1
WHERE C1>500
Exemplu:
Selecţie
SELECT *
FROM R1
WHERE C3>250 AND C3<=350
Exemplu:
Selecţie
SELECT *
FROM R1
WHERE C1>300 AND C3>300
Exemplu:
Care sunt studenţii Facultăţii de Ştiinţe Economice?
SELECT *
FROM STUDENT
WHERE facultate = „Stiinte Economice”
Exemplu:
Care sunt studenţii Facultăţii de Ştiinţe Economice, specializarea Contabilitate şi Informatică de
Gestiune?
SELECT *
FROM STUDENT
WHERE (((STUDENT.Facultate)="Stiinte Economice") AND
((STUDENT.Sectia)="CIG"));
Exemplu:
Ce burse au fost încasate în primele două săptămâni din luna martie 2017?
Formatul general al unei constante de tip dată calendaristică este YYYY-MM-DD, interogarea în
SQL-92 poate avea forma.
SELECT *
FROM BURSA
WHERE data_încasarii>=’2017/03/01’ AND
data_încasarii<=’2017/03/15’
În Microsoft Access interogarea arată astfel:
SELECT BURSA.*
FROM BURSA
WHERE (((BURSA.[Data incasarii])>=#3/15/2017# And (BURSA.[Data
incasarii])<=#3/20/2017#));
Exemplu:
Proiecţie
SELECT C3
FROM R1
Exemplu:
Proiecţie
SELECT C1, C3
FROM R1
Exemplu:
Care sunt facultăţile preluate în bază?
SELECT facultate
FROM STUDENT
Exemplu:
Care sunt: cota, titlul, domeniul şi număr de exemplare al fiecărei cărţi?
Exemplu:
Care este facultatea pe care o urmează studentul Barbu Costel?
SELECT facultate
FROM STUDENT
WHERE nume = „Neacsu Florin”
Exemplu:
Care sunt regiunile din care fac parte judeţele Dâmboviţa şi Dolj?
Exemplu:
Care sunt studenţii Facultăţii de Ştiinţe Economice de la specializările CIG şi FA?
Exemplu:
Care sunt cărţile care au apărut la editurile Eficient şi Macarie?
SELECT titlu
FROM CARTE
WHERE editura = „Eficient” OR editura = „Macarie”
Reuniunea
SELECT *
FROM R1
UNION
SELECT *
FROM R2
Exemplu:
Care sunt studenţii Facultăţii de Ştiinţe Economice de la specializările CIG şi FA? -, fraza SQL
echivalentă cu soluţia 2 bazată pe reuniune este:
SELECT nume
FROM STUDENT
WHERE facultate = „Stiinte Economice” AND sectia = „CIG”
UNION
SELECT nume
FROM STUDENT
WHERE facultate = „Stiinte Economice”
AND sectia =„FA”
Intersecţia
SELECT *
FROM R1
INTERSECT
SELECT *
FROM R2
Exemplu:
Care sunt cărţile care au apărut la editurile Teora şi Nemira?
SELECT titlu
FROM CARTE
WHERE editura = „Teora”
INTERSECT
SELECT tilu
FROM CARTE
WHERE editura = „Nemira”
Diferenţa
Operatorul la care ne-am aştepta în acest caz ar fi MINUS. În Standardul SQL – 92 şi în alte câteva
SGBD-uri operatorul MINUS nu există, el fiind substituit de EXCEPT, în timp ce în alte SGBD-uri nu
există nici unul, nici altul:
SELECT *
FROM R1
EXCEPT
SELECT *
FROM R2
Produsul cartezian
SQL nu pune la dispoziţie vreun operator special dedicat produsului cartezian şi asta din simplul
motiv că nici nu este nevoie să o facă. Tabela obţine pur şi simplu prin enumerarea celor două relaţii în
clauza FROM.
SELECT *
FROM R1, R2
În multe interogări SQL o facilitate importantă o constituie definirea, pe lângă atributele tabelelor, a
unor coloane noi (virtuale), pe baza unor expresii. Clauza AS permite denumirea coloanelor calculate sau
redenumirea unor coloane ale tabelelor.
Să luăm următorul exemplu:
Exemplu:
Care este valoaerea de achiziţie pentru fiecare carte cu titlul „Baze de date”?
Rezultatul acestei interogări este prezentat în figura de mai jos. Observăm că pentru fiecare din cele
trei cărţi baze de date, a fost calculată o valoarea de achiziţie, ca rezultat al înmulţirii câmpurilor Numar
exemplare şi Pret unitar. Titlul acestei coloane este atribuit de către Microsoft Acces, iar în cazul de faţă
aceasta este Expr1003.
A patra coloană este denumită Valoarea totala, după cum a fost specificat în clauza AS. Valorile
sale sunt determinate pe baza expresiei pret_unitar*numar exemplare.
În ceea ce priveşte expresiile de tip dată calendaristică, modurile în care au fost implementate aceste
funcţiuni sunt foarte eterogene de la SGBD la SGBD.
Exemplu:
Să presupunem că orice carte împrumutată trebuie restituită în maximum 10 zile.
Exemplu:
Dacă am presupune că o carte împrumutată poate fi restituită peste 2 luni, interogarea de mai sus
trebuie modificată astfel:
Am folosit funcţia DateAdd pentru a adăuga 2 luni la câmpul data imprumut, lunile au fost
menţionate în primul argument, respectiv “m”, de la month.
Dacă vrem să punem în evidenţă operaţiunile de adunare şi scădere între două date calendaristice, să
luăm exemplul în care ne interesează intervalul dintre momentul curent (data curentă) şi momentul
împrumutării fiecărei cărţi:
Rezultatul scăderii a două date calendaristice este un numeric care reprezintă numărul de zile.
5.5. Opţiunea ORDER BY
Una din caracteristicile modelului relaţional este faptul că din punct de vedere informaţional, nici
ordinea atributelor, nici ordinea liniilor în relaţii nu prezintă importanţă. Cu toate acestea, în practică
forma de prezentare a rezultatelor interogării este foarte importantă. Spre exemplu o listă a tuturor
localităţilor este cu mult mai folositoare dacă este prezentată în ordine alfabetică, posibilă prin clauza
ORDER BY.
Exemplu:
Să se obţină lista localităţilor în ordine alfabetică.
SELECT *
FROM LOCALITATE
ORDER BY nume_localitate
Implicit aranjarea se face crescător (ASC). Prin opţiunea DESC, ordinea prezentării se inversează. În
plus se pot specifica mai multe coloane care să servească drept criterii suplimentare de ordonare. La
valori egale ale primului atribut, intră în acţiune criteriul de „balotaj” care este al doilea atribut ş.a.m.d.
Exemplu:
Să se obţină în ordinea descrescătoare a editurilor şi crescătoare a titlurilor, lista cărţilor din bibliotecă.
Pentru formularea predicatului de selecţie, SQL permite utilizarea, pe lângă „clasicii” >, ≥, <, ≤, =, ≠
şi a altor operatori, dintre care noi ne vom opri doar asupra lui BETWEEN (între, cuprins între), LIKE (ca
şi, la fel ca) şi IN (în).
Exemplu:
Care sunt studenţii care s-au născut în anul 1982.
Soluţia la exemplul de mai sus, în condiţiile în care nu se folosea BETWEEN, ar fi folosit în clauza
WHERE, o condiţie compusă, respectiv:
De multe ori, când se doreşte obţinerea unor informaţii din bază suntem puşi în postura de a nu şti cu
exactitate cum se numeşte un student sau o carte. Acestea sunt situaţiile pentru a căror rezolvare a fost
gândit operatorul LIKE.
Operatorul LIKE permite compararea unui atribut (expresii) cu un literal utilizând o „mască”
construită cu ajutorul specificatorilor multipli % sau _ . Procentul (%) substituie un şir de lungime
variabilă, 0-n caractere, în timp ce liniuţa (_) substituie un singur caracter.
Exemplu:
Care sunt cărţile din bibliotecă care încep cu litera „M”?
SELECT titlu
FROM CARTE
WHERE titlu LIKE 'M*'
SELECT *
FROM CARTE
WHERE LEFT(titlu,1)='M'
S-a folosit funcţia LEFT() pentru a extrage prima literă din câmpul Titlu.
LEFT returnează primul caracter sau primele caractere dintr-un șir text, pe baza numărului de
caractere specificat.
LEFT(text, [car_num])
Text - Obligatoriu. Șirul text care conține caracterele pe care doriți să le extrageți.
Car_num - Opțional. Specifică numărul de caractere pe care doriți să le extragă LEFT.
Car_num trebuie să fie mai mare sau egală cu zero.
Dacă car_num este mai mare decât lungimea textului, LEFT returnează tot textul.
Dacă este omis car_num, se presupune că este 1.
Sursa: https://support.office.com/ro-ro/article/LEFT-LEFTB-func%C8%9Biile-LEFT-LEFTB-9203d2d2-
7960-479b-84c6-1ea52b99640c
Exemplu:
Ce cărţi au titlul conţinând litera „e” pe a treia poziţie?
SELECT *
FROM CARTE
WHERE titlu LIKE „_ _ e%”
Microsoft Access nu face diferenţă între forma de scriere a literei („e” sau „E”), ca atare varianta
folosită pentru a ilustra exemplul de mai sus este următoarea:
SELECT *
FROM CARTE
WHERE (((Mid([titlu],3,1))='e';
S-a folosit funcţia MID() pentru a extrage un subşir (litera e) dintr-un şir (Câmpul Titlu).
MID întoarce un anumit număr de caractere dintr-un șir de text, începând din poziția specificată, pe
baza numărului de caractere specificat.
Sintaxa funcției MID este următoarea:
Text - Obligatoriu. Șirul text care conține caracterele pe care doriți să le extrageți.
Num_start - Obligatoriu. Este poziția din text a primului caracter pe care vreți să-l extrageți. Pentru
primul caracter din text, num_start este 1 și așa mai departe.
Car_num - Obligatoriu. Specifică numărul de caractere ce trebuie returnate de MID din text.
Observații:
Dacă num_start este mai mare decât lungimea textului, MID întoarce "" (text gol).
Dacă num_start este mai mic decât lungimea textului, dar suma num_start plus car_num
depășește lungimea textului, MID întoarce caracterele până la sfârșitul textului.
Dacă num_start este subunitar, MID întoarce valoarea de eroare #VALUE!.
Dacă car_num este negativ, MID întoarce valoarea de eroare #VALUE!.
Sursa: https://support.office.com/ro-ro/article/mid-midb-func%C8%9Biile-mid-midb-d5f9e25c-d7d6-
472e-b568-4ecb12433028
Exemplu:
Care sunt cărţile al căror titlu se termină în literele „ce”?
SELECT *
FROM CARTE
WHERE titlu LIKE „%ce”
SELECT *
FROM CARTE
WHERE RIGHT(titlu,2)='ce'
Observăm folosirea funcţiei RIGHT() pentru a extrage caracterele din dreapta. S-a folosit funcţia
RIGHT() pentru a extrage ultimele două litere din câmpul Titlu.
RIGHT returnează primul caracter sau primele caractere dintr-un șir text, pe baza numărului de
caractere specificat.
RIGHT(text, [car_num])
Text - Obligatoriu. Șirul text care conține caracterele pe care doriți să le extrageți.
Car_num - Opțional. Specifică numărul de caractere pe care doriți să le extragă RIGHT.
Car_num trebuie să fie mai mare sau egală cu zero.
Dacă car_num este mai mare decât lungimea textului, RIGHT returnează tot textul.
Dacă este omis car_num, se presupune că este 1.
5.6.3. Operatorul IN
Atunci când se testează dacă valoarea unui atribut este încadrabilă într-o listă dată de valori, în locul
folosirii abundente a operatorului OR, o soluţie mult mai elegantă este să se facă apel la operatorul IN.
Formatul general este:
Rezultatul evaluării unui predicat ce conţine acest operator va fi adevărat dacă valoarea expresiei1
este cel puţin egală cu una dintre valorile expresie2, expresie3, ....
Exemplu:
Care sunt studenţii care urmează specializările CIG, MG şi MK?
- fără operatorul IN
SELECT *
FROM STUDENT
WHERE sectia = „CIG” OR sectia = „MG”
OR sectia = „MK”
- cu operatorul IN
SELECT *
FROM STUDENT
WHERE sectia IN („CIG”, „MG”, „MK”)
Exemplu:
Care sunt cărţile care au apărut în anii 1999, 2001 şi 2002?
- fără operatorul IN
SELECT *
FROM CARTE
WHERE an_aparitie=1999 OR an_aparitie=2001
or an_aparitie=2002
- cu operatorul IN
SELECT *
FROM CARTE
WHERE an_aparitie IN (1999, 2001, 2002)
Exemplu:
Ce burse s-au încasat pe 16, 18 şi 20 februarie 2019?
- fără operatorul IN
SELECT *
FROM BURSA
WHERE data_incasarii = 2019/02/16
OR data_incasarii = 2019/02/18
OR data_incasarii = 2019/02/20}
- cu operatorul IN
SELECT *
FROM BURSA
WHERE data_incasarii IN (2019/02/16,
2019/02/18, 2019/02/20)