Sunteți pe pagina 1din 14

5.3.

Elemente de bază ale interogărilor SQL

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:

SELECT [ALL/DISTINCT/] lista_atribute


FROM lista_tabele
[WHERE criteriu_de_căutare]
[GROUP BY atribut_de_grupare]
[HAVING criteriu_de_grupare]
[ORDER BY criteriu_de_ordonare [ASC/DESC]];

unde:
lista_atribute - specifică atributele ale căror valori vor fi returnate

nume_tabele - specifică tabelele din care se vor extrage datele

ALL - specifică returnarea tuturor tuplurilor care îndeplinesc


condiţiile precizate în blocul de cerere

DISTINCT - elimină tuplurile care prezintă valori duplicate conţinute în


atributele specificate

WHERE - permite, prin precizarea unei expresii, exprimarea criteriului


de selecţie

ORDER BY - precizează atributul după care se va face ordonarea

GROUP BY - folosit pentru a partiţiona o relaţie în grupuri, acordând


acestora valori pe un atribut sau listă de atribute
HAVING - folosit pentru a specifica criterii de selecţie pe grupuri de
tupluri

Î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:

SELECT C1, C2, ..., Cn


FROM T1, T2, ..., Tm
WHERE P

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.

SELECT DISTINCT C1, C2, ..., Cn


FROM T1, T2, ..., Tm
WHERE P

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?

SELECT cota carte, titlu, domeniu, numar exemplare


FROM CARTE

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?

SELECT judet, regiune


FROM LOCALITATE
WHERE judet = „Dambovita” OR judet = „Dolj”

Exemplu:
Care sunt studenţii Facultăţii de Ştiinţe Economice de la specializările CIG şi FA?

SELECT nume, sectia


FROM STUDENT
WHERE facultate = „Stiinte Economice” AND
sectia = „CIG” OR sectia = „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”

Reuniune, intersecţie, diferenţă, produs cartezian


Primii trei operatori asamblişti prezintă operatori SQL dedicaţi: UNION, INTERSECT, MINUS
(EXCEPT) în timp ce produsul cartezian se obţine automat prin simpla enumerare a celor două tabele în
clauza FROM.

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”

Exemplul de mai sus funcţionează în Oracle.

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

5.4. Coloane expresii

Î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”?

SELECT CARTE.Titlu, CARTE.[Numar exemplare],


CARTE.[Pret unitar], [Pret unitar]*[Numar exemplare]
FROM CARTE
WHERE (((CARTE.Titlu)="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.

Titlu Numar exemplare Pret unitar Expr1003


Baze de date 55 30 1650
Baze de date 42 31 1302
Baze de date 21 40 840

Pentru a atribui nume campului, vom folosi clauza AS în fraza SELECT.

SELECT CARTE.Titlu, CARTE.[Numar exemplare], CARTE.[Pret


unitar], [Pret unitar]*[Numar exemplare] AS [Valoarea totala]
FROM CARTE
WHERE (((CARTE.Titlu)="Baze de date"));

Titlu Numar exemplare Pret unitar Valoarea totala


Baze de date 55 30 1650
Baze de date 42 31 1302
Baze de date 21 40 840

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.

SELECT STUDCARTE.[Cota carte], STUDCARTE.[Data imprumut],


[Data imprumut]+10 As [Data Restituire]
FROM STUDCARTE;

Exemplu:
Dacă am presupune că o carte împrumutată poate fi restituită peste 2 luni, interogarea de mai sus
trebuie modificată astfel:

SELECT STUDCARTE.[Cota carte], STUDCARTE.[Data imprumut],


DateAdd('m',2,[data imprumut]) AS [Data restituire]
FROM STUDCARTE;

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.

Exemplul anterior cu cele 10 zile, folosind funcţia DateAdd, se scrie astfel:

SELECT STUDCARTE.[Cota carte], STUDCARTE.[Data imprumut],


DateAdd('d',10,[data imprumut]) AS [Data restituire]
FROM STUDCARTE;

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:

SELECT STUDCARTE.[Cota carte], STUDCARTE.[Data imprumut],


Date()-[Data imprumut] AS [Timp scurs]
FROM STUDCARTE;

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ă.

SELECT cota carte, titlu, editura


FROM CARTE
ORDER BY editura DESC, titlu ASC

5.6. Operatorii BETWEEN, LIKE, IN

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).

5.6.1. Operatorul BETWEEN

Este util pentru definirea intervalelor de valori.

Exemplu:
Care sunt studenţii care s-au născut în anul 1982.

SELECT STUDENT.Nume, STUDENT.Facultate,


STUDENT.[Data nasterii]
FROM STUDENT
WHERE (((STUDENT.[Data nasterii])
Between #1/1/1996# And #12/31/1996#));

Rezultatul este prezentat în figura de mai jos:


Nume Facultate Data nasterii
Soare Paul Stiinte Umaniste 9/21/1996
Bojianu Mirela Stiinte Economice 6/5/1996
Balasa Mihai Stiinte Economice 10/11/1996
Ionescu Octavian Stiinte Umaniste 10/19/1996
Vasilescu Ada Stiinte Umaniste 5/10/1996

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:

SELECT STUDENT.Nume, STUDENT.Facultate,


STUDENT.[Data nasterii]
FROM STUDENT
WHERE (((STUDENT.[Data nasterii])>=#1/1/1996#
And (STUDENT.[Data nasterii])<#12/31/1996#));
Exemplu:
Să se obţină în ordinea apariţiei, lista cărţilor din bibliotecă care au numărul de exemplare cuprins între
50 şi 100.

SELECT CARTE.Titlu, CARTE.[Numar exemplare]


FROM CARTE
WHERE (((CARTE.[Numar exemplare]) Between 50 And 100))
ORDER BY CARTE.[An aparitie] DESC;

Rezultatul se prezintă astfel:

Titlu Numar exemplare An aparitie


Drept penal 58 2015
Microeconomie 63 2014
Proiectarea bazelor de date 78 2014
Modele de aplicaţii practice în Microsoft Excel 59 2010
Microfost Office - Access 85 2010
Microfost Office - Word 58 2002
Baze de date 55 1999

Soluţia fără BETWEEN:

SELECT CARTE.Titlu, CARTE.[Numar exemplare]


FROM CARTE
WHERE (((CARTE.[Numar exemplare])>=50
And (CARTE.[Numar exemplare])<=100))
ORDER BY CARTE.[An aparitie] DESC;
5.6.2. Operatorul LIKE

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*'

Rezultatul se prezintă astfel:


titlu
Microfost Office - Word
Microfost Office - Excel
Microfost Office - Access
Microfost Office - PowerPoint
Modele de aplicaţii practice în Microsoft Excel
Microeconomie
Macroeconomie
Managementul resurselor umane
Marketing. De la practica la teorie

Varianta fără LIKE ar fi fost următoarea:

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%”

Rezultatul se prezintă astfel:


Cota An Numar Pret
Titlu Editura Domeniu
carte aparitie exemplare unitar
1134 Drept comercial Nemira Drept 2004 45 32
1135 Drept Nemira Drept 2008 47 60
adminstrativ
1136 Drept penal Nemira Drept 2015 58 42

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:

MID(text, num_start, car_num)

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”

Rezultatul se prezintă astfel:


Cota An Numar Pret
Titlu Editura Domeniu
carte aparitie exemplare unitar
1121 Proiectarea Bibliotheca Informatica 2016 10 40
sistemelor
informatice
1133 Contabilitatea Teora Contabilitate 2009 10 50
institutiilor publice

Varianta fără LIKE:

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:

expresie1 IN (expresie2, expresie3, ...)

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)

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