Sunteți pe pagina 1din 64

LIMBAJUL SQL

SQL (Structured Query Language), a fost conceput iniial de firma IBM, pentru produsul dBASE, ca un limbaj standard de descriere a datelor i de acces la informtiile din bazele de date. Limbaj de interogare a bazelor de date relaionale, SQL a fost utilizat pe scar larg i pan n prezent au fost dezvoltate apte versiuni ale standardului SQL, trei dintre ele aparinnd Institutului National American de Standarde (ANSI), celelalte fiind concepute de firme de prestigiu ca IBM, Microsoft i Borland sau de ctre consorii ca SAG (The SQL Access Group) i X/Open.

Primul standard SQL a fost creat in anul 1989 de ctre ANSI fiind cunoscut sub numele de ANSISQL'89 i a fost revizuit in octombrie 1992 sub noua denumire: ANSI-SQL'92. In anul 1992, firma Microsoft, in calitate de membru SAG, a lansat pe piata produsul ODBC (Open Database Connectivity), un standard API-SQL care defineste o interfat de programare a aplicaiilor (API) pentru accesul la bazele de date.

Clauzele SELECT, FROM i WHERE Clauzele SQL SELECT, FROM i WHERE pot fi puse n corespondent cu operatorii din algebra relaional, dupa cum urmeaza: clauza SELECT mentioneaza o lista de atribute i corespunde proiectiei din algebra relaional; clauza FROM mentioneaz o list de relatii (tabele) i corespunde produsului cartezian din algebra relaionala; clauza WHERE descrie un predicat de selectie i corespunde selectiei din algebra relaional.

O interogare simpla SQL este de forma: SELECT A1, A2, ..., An FROM R1, R2, ..., Rm WHERE P Unde: Ai sunt atribute care apar n cel putin una dintre relatiile Ri; Ri sunt relatii (tabele); P este un predicat de selectie. Interogarea este echivalent cu urmatoarea expresie din algebra relaional: A1,A2,,An(p(R1 X R2 XXRm))

In SQL, "select" desemneaza proiectia iar in algebra relaionala acelasi termen desemneaza selectia dupa un predicat de selectie. Lista de atribute care apare in clauza SELECT din SQL poate fi inlocuita cu simbolul * daca se doreste selectarea tuturor atributelor care apar in relatiile din clauza FROM. Intotdeauna rezultatul unei interogari SQL este o relatie (o tabela).

Tabela FURNIZORI cu schema de relatie (cod_furnizor, nume_furnizor, adresa_furnizor). Tabela FLORI cu schema de relatie (cod_produs, nume_produs, culoare, inaltime, pret_unitar). Tabela COMENZI cu schema de relatie (nr_comanda, cod_produs, cod_furnizor, data_comenzii, timp_livrare, cantitate).

1) "Sa se afiseze toate datele despre toti furnizorii" SELECT * FROM furnizori 2) "Sa se afiseze orasele de resedinta ale tuturor furnizorilor" SELECT oras FROM furnizori Ca rezultat al acestei interogari se va obtine o tabela cu o singura coloana, care contine numele oraselor de resedinta ale furnizorilor. Se va observa ca se repeta numele oraselor, deoarece se vor afisa orasele pentru fiecare furnizor in parte din tabela FURNIZORI.

O interogare SQL are urmatoarea forma generala: SELECT [DISTINCT/ALL] <lista de atribute> FROM <lista de relatii> [WHERE <conditie> / GROUP BY< lista de atribute> / HAVING <conditie> / ORDER BY <lista de atribute> [ASC / DESC] / UNION <sub_interogare>]; ... ...

Dup cum se observ, singurele elemente obligatorii intr-o interogare SQL sunt clauzele SELECT cu lista de atribute ce vor fi extrase i clauza FROM cu relatiile din care fac parte atributele. Asadar o interogare SQL trebuie sa contina cel putin urmatoarele informatii: SELECT <lista de atribute> FROM <lista de relatii> restul clauzelor sunt optionale.

Lista de atribute poate consta din : o serie de atribute separate prin virgul care vor aprea n tabelarezultat n ordinea explicitat n linia de comand, de la stanga la dreapta; toate atributele din relatia asupra careia se aplica interogarea, n ordinea n care au fost definite n aceast relatie (in locul acestei liste se poate utiliza semnul "*"); expresii formate din urmatoarele elemente: -atribute i operatori aritmetici (de exemplu: cantitate*pret_unitar) -functii standard (de exemplu CTOD( )); -constante; -variabile de memorie. expresii care contin functii SQL agregat cum ar fi AVG( ), MAX( ), MIN( ), COUNT( ), SUM( ) ...

In exemplele de mai sus, pentru a evita repetarea unor informatii in tabelele rezultat se poate utiliza cuvintul cheie DISTINCT. Optiunea DISTINCT permite eliminarea tuplelor duplicat. In acest mod numai prima aparitie a unui tuplu este afisat n tabela-rezultat. EXEMPLU: "Sa se afiseze toate orasele resedinte ale furnizorilor, dar sa apara fiecare oras o singura data in tabelarezultat" SELECT DISTINCT oras FROM furnizori

Clauza FROM are forma generala: FROM <<nume relatie>/ <nume view>[<alias>] ... > si specifica relatiile (pot fi i nume de view) din care vor fi regsite datele. In cazul n care se operaz cu mai multe tabele, este util atribuirea unor prescurtri, (numite alias) numelor de tabele ce vor fi utilizate n interogare.

1) "Sa se afiseze codurile furnizorilor i numerele de comanda corespunzatoare pentru toti furnizorii care a cel putin o comanda" SELECT 1.cod_furnizor, B.numar_comanda FROM furnizori 1, comenzi B WHERE 1.cod_furnizor=B.cod_furnizor

2) "Sa se afiseze codurile furnizorilor, numele furnizorilor, cantitatile, i numerele comenzilor pentru toti furnizorii care au cel putin o comanda" SELECT A.cod_furnizor, nume_furnizor, cantitate, numar_comanda FROM furnizori A, comenzi B WHERE A.cod_furnizor=B.cod_furnizor

A se observa ca in al doilea exemplu nu sa mai utilizat notatia cu alias pentru atributul numar_comanda din tabela comenzi deoarece nu este pericol de confuzie. In schimb s-a utilizat notatia pentru a deosebi atributul cod_furnizor din tabela furnizori de atributul cu acelasi nume din tabela comenzi.

Pentru a restrange tuplele ce apar n tabela-rezultat, se specific o conditie de cutare prin utilizarea unui predicat de selectie in clauza WHERE. Clauza WHERE are forma generala: WHERE <predicat> / <expresie>; Numai tuplele care satisfac predicatul de selectie vor fi incluse in tabela-rezultat

Predicatul de cutare poate fi specificat printr-o conditie logica in care se utilizeaza urmatoarele elemente: operatori: - aritmetici: + - / * ** ^ - relaionali: < > <= >= <> != = - logici: NOT AND OR - operatori SQL: IN, EXISTS, ALL, ANY

sub-interogri (exprimate prin interogari SQL),cu observatia c acestea vor fi primele evaluate i tabela-rezultat trebuie s corespund operatorilor ce i se aplic n continuare. Operatorii aritmetici Acesti operatori sunt binecunoscuti i mentionam aici doar faptul ca i ** i ^ reprezinta ridicarea la putere. Ca operanzi, se pot utiliza atribute, constante, functii sau expresii algebrice. Expresiile algebrice pot aparea in clauzele SELECT sau WHERE.

"Sa se afiseze codul produsului i valoarea pe care o reprezinta cantitatea de produs comandata la diversi furnizori" SELECT cod_produs, cantitate*pret_unitar FROM comenzi WHERE cantitate<>0

Operatorii relaionali < mai mic > mai mare ! negarea operatorilor <, >, =. Se obtin operatorii: !=(diferit), !<(nu mai mic), !>(nu mai mare). <= mai mic sau egal => mai mare sau egal <> diferit Facem observatia c valorile comparate trebuie s apartin unor tipuri de date compatibile (care se pot compara intre ele).

"Sa se afiseze codurile plantelor de culoare alba." SELECT cod-produs FROM flori WHERE culoare='alb'

Operatorii logici Dac o clauz WHERE contine mai multe conditii formate prin utilizarea aceluiasi tip de oparator logic, evaluarea se va face de la stanga la dreapta. tipul de operator logic este dat de precedenta operatorilor. Operatorul NOT are cea mai mare prioritate, urmat de AND i OR care practic sunt de prioritati egale. Pentru a schimba ordinea de evaluare a unei expresii se utilizeaz parantezele rotunde ().

1) "Sa se afiseze numele plantelor de culoare alba i de inaltime minima 50 cm" SELECT nume_planta FROM flori WHERE culoare='alb' AND inaltime>=50 2) "Sa se afiseze numele, culoarea i inaltimea plantelor care fie au culoarea alba fie sunt de inaltime mai mica de 50 cm" SELECT nume_planta, culoare, inaltime FROM flori WHERE (culoare='alb) OR (inaltime<50)

3) A se observa ca ultima interogare este echivalenta cu interogarea SELECT nume_planta, culoare, inaltime FROM flori WHERE culoare='alb' OR NOT inaltime>=50

Ordonarea tuplelor (clauza ORDER BY) n exemplele anterioare, tuplele tabelei-rezultat apar n aceeasi ordine n care au fost introduse. Pentru modificarea ordinii de afisare se utilizeaz clauza ORDER BY. Forma generala a acestei clauze este: ORDER BY <(<nume atribut>/<numr ntreg>)(ASC/ DESC)>,... Tuplele sunt ordonate n mod implicit n ordine ascendent (ASC). Ordinea este: 0,...,9,A,...,Z,a,...,z conform codului ASCII. Afisarea n ordine descresctoare se poate face prin utilizarea optiunii DESC.

"Sa se afiseze datele despre florile din evidente in ordinea alfabetica a numelor florilor." SELECT * FROM flori ORDER BY nume_planta, ASC A se observa ca daca ar fi lipsit mentiunea ASC, ordinea tuplelor ar fi fost aceeasi deoarece ordinea ascendenta este implicita. n loc de precizarea numelui atributului dup care se face ordonarea, se poate preciza pozitia atributului n lista de atribute specificate n comanda SELECT. EXEMPLU: SELECT oras, cod_furnizor, nume_furnizor FROM furnizori ORDER BY 1 DESC, 3 ASC

Operatorul IN permite simplificarea predicatului de cutare. Predicatul IN testeaz dac valoarea unui atribut specificat n lista de atribute din clauza WHERE se potriveste uneia din valorile listei specificate n predicatul IN (testeaz apartenenta la o multime). "Sa se afiseze toate datele despre furnizorii care au sediul in Bucuresti sau in Brasov sau in Cluj" SELECT * FROM furnizori WHERE oras IN ('BUCURESTI', 'BRASOV', 'CLUJ')

Functii standard Functiile standard, cunoscute i sub numele de functii agregat, apar in clauza SELECT i se aplica atributelor din tabelele implicate in interogare. Functii standard sunt: -valoarea medie - AVG -valoarea minima - MIN -valoarea maxima - MAX -total(sumare) - SUM -numrtoare - COUNT NOTA: Nu este permisa utilizarea acestor functii in clauza WHERE deoarece ele actioneaza la nivel de atribut i nu la nivel de tuplu.

1) "Care este cantitatea minima comandata?" SELECT MIN(cantitate) FROM comenzi Spre exemplu,urmtoarea interogare are ca rezultat afisarea cantittii totale i a numrului de produse din fisierul de comenzi. SELECT SUM(cantitate), COUNT(*) FROM comenzi 2) "Care este cantitatea medie comandata?" SELECT AVG(cantitate) FROM comenzi

3) "Care este cantitatea totala comandata din planta cu cod '202'?" SELECT SUM(cantitate) FROM comenzi WHERE cod_produs='202' 4) "Cate tuple contine tabela de flori?" SELECT COUNT(*) FROM flori 5) "Cate culori de flori sunt inregistrate pentru florile din fisier?" SELECT COUNT(DISTINCT culoare) FROM flori

Gruparea rezultatelor (clauza GROUP BY) n multe cazuri, utilizatorul doreste anumite situatii sintetice, cum ar fi obtinerea de totaluri i subtotaluri. Pentru aceaste operatii, limbajul SQL permite utilizarea clauzelor GROUP BY i HAVING. Aceste clauze organizeaz tuplele n grupuri asupra crora se pot realiza anumite operatii, n special prin aplicarea functiilor agregat.

Clauza GROUP BY grupeaz tuplele din relatie dup atributele cu aceeasi valoare care sunt specificate n clauz, i generez un singur tuplu pentru fiecare grup de tuple cu aceeasi valoare pe atribut. Atributele care apar n clauza SELECT pot fi de dou feluri: - atribute care alctuiesc baza pentru grupare (cele care apar n clauza GROUP BY) - atribute care nu participa la gruparea rezultatelor, dar sunt constante pentru grup.

1) "In ce orase exista furnizori ai florariei?" SELECT oras FROM furnizori GROUP BY oras In urma executarii interogarii vor apare orasele din fisierul de furnizori listate o singura data. 2) "Cati furnizori au sediul in fiecare oras?" SELECT oras, COUNT(*) FROM furnizori GROUP BY oras

3) "In care orase locuiesc cel putin 3 furnizori?" SELECT oras, COUNT(*) FROM furnizori GROUP BY oras HAVING COUNT(*)>=3 Clauza GROUP BY se poate folosi i cu clauzele ORDER BY i WHERE.

2) "Care furnizori livreaza in interval de cel mult 17 zile?" SELECT cod_furnizor FROM comenzi WHERE timp_livrare<17 GROUP BY cod_furnizor

Interogari pe mai multe tabele Una dintre operatiile cele mai frecvente realizate cu mai multe tabele este jonctiunea sau produsul cartezian. Jonctiunea aminteste de operatiile din algebra relaionala i chiar este posibil de realizat (urmand anumite structuri ale interogarii SQL) oricare dintre tipurile de jonctiune prezentate teoretic in cadrul algebrei relaionale. Se pot de asemenea realiza operatii ca reuniunea, intersectia i diferenta. Sintaxa interogarii SQL difera de la un SGBD la altul dar sub o forma directa sau printr-o constructie sintactica specifica se pot realiza oricare dintre operatiile amintite.

1) "Sa se afiseze codurile furnizorilor, numele furnizorilor, cantitatile comandate i numerele comenzilor" SELECT 1.cod_furnizor, nume_furnizor, cantitate, nr_comanda FROM furnizori 1, comenzi b WHERE 1.cod_furnizor=b.cod_furnizor A se observa scrierea cu notarea tuplelor care apartin fiecarei tabele pentru a evita orice confuzie in legatura cu tabela din care se va extrage informatia. Exista doua atribute in tabele diferite care au acelasi nume: atributele cod_furnizor. Modul de notare de mai sus este acceptat de sintaxa SQL i diferentiaza atributul cod_furnizor din tabela furnizori de atributul cod_furnizor din tabela comenzi.

2) "Sa se afiseze datele de mai sus dar numai pentru furnizorii care au adresa in Brasov" SELECT 1.cod_furnizor, nume_furnizor, cantitate, nr_comanda FROM furnizori 1, comenzi b WHERE 1.cod_furnizor=b.cod_furnizor AND oras='Brasov'

3) "Ce flori au aceeasi inaltime cu laleaua?" A se observa ca aceasta interogare necesita realizarea produsului cartezian al tabelei FLORI cu ea insasi. SELECT p1.nume_planta, p2.nume_planta, p1.inaltime, p2.inaltime FROM flori p1, flori p2 WHERE p1.inaltime=p2.inaltime AND p2.nume_planta='LALEA'

Clauza UNION Clauza UNION permite realizarea reuniunii de tabele. In cazul cand dorim sa reunim doua sau mai multe tabele, este obligatoriu ca acestea sa fie descrise de scheme de relatie identice (acelasi numar de atribute i corespunzator de la stanga la dreapta atributele din tabele au acelasi nume i aceeasi descriere). Aceste conditii sunt impuse tabelelor implicate in operatiile intersectie i minus (diferenta). Operatiile reuniune, intersectie i diferenta de tabele actioneaza analog cu aceleasi operatii aplicate la multimi.

Forma generala a reuniunii de tabele este: SELECT A1 ,, Am FROM [WHERE ] UNION SELECT A1 ,, Am FROM [WHERE ]

1) "Sa se afiseze numele plantelor i codurile plantelor albe care au inaltimea fie mai mica decat 20 cm fie mai mare decat 50 cm." SELECT nume_planta, cod_produs FROM flori WHERE culoare='alb' AND inaltime<20 UNION (SELECT nume_planta, cod_produs FROM flori WHERE culoare='alb' AND inaltime>50)

. Subinterogari (clauze SELECT imbricate) Unul din motivele pentru care SQL este considerat un limbaj puternic de interogare este acela c ofer posibilitatea construirii interogrilor complexe, formate din mai multe subinterogri simple. Aceste interogri complexe sunt construite prin includerea n clauza WHERE a inca unei clauze SELECT.

. Forma generala a unei astfel de constructii este: SELECT < lista atribute1 > FROM < lista relatii1 > WHERE < subinterogare > Se observa ca aceasta constructie a fost deja utilizata in exemplul de mai sus care ilustreaza o clauza UNION.

In constructia de mai sus clauza SELECT interioar genereaz valorile pentru conditia de cutare a clauzei SELECT exterioare care o contine. Clauza SELECT exterioar genereaz o relatie pe baza valorilor generate de ctre clauza interioar. Modul de constuire a interogrii exterioare depinde de numrul valorilor returnate de ctre interogarea interioar .n acest sens, putem distinge: - subinterogri care returneaz o singur valoare - subinterogri care returneaz mai multe valori.

Din punctul de vedere al ordinii de evaluare al interogrilor putem distinge: subinterogri simple Interogarea interioar este evaluat prima, independent de interogarea exterioar. Rezultatul evalurii interogrii interioare este utilizat de ctre interogarea exterioar . subinterogri corelate Valorile returnate de ctre interogarea interioar depind de valorile returnate de ctre interogarea exterioar. Interogarea interioar este evaluat repetat pentru fiecare tuplu cercetat de interogarea exterioara.

Subinterogri simple care returnez o singur valoare Aceste interogri au urmtoarea sintax: SELECT < lista atribute > FROM < lista relatii > WHERE < atribut > (< subinterogare >) unde este un operator relaional: = < > >= <= !=

SELECT nume_planta FROM flori WHERE inaltime= (SELECT inaltime FROM flori WHERE nume_planta='LALEA') Aceeasi interogare poate oferi lista numelor de plante in ordine alfabetica inversa daca se utilizeaza i o clauza ORDER BY. SELECT nume_planta FROM flori WHERE inaltime= (SELECT inaltime FROM flori WHERE nume_planta='LALEA') ORDER BY nume_planta DESC

Procesul de evaluare a acestei interogri se desfsoar astfel: Se evalueaz n primul rnd interogarea interioar. Conditia de evaluare a interogrii interioare este nume_planta='LALEA'. Valoarea obtinuta pentru atributul inaltime (sa presupunem ca laleaua are 30 cm) este stocata ntr-o tabela temporara. Rezultatul evalurii interogrii interioare devine conditie de cutare pentru interogarea exterioar, care ar putea fi exprimata in aceasta faza ca: SELECT nume_planta FORM flori WHERE inaltime=30

In urma executarii interogarii exterioare este creat o relatie final, ce va contine tuplele a cror inaltime este aceeasi cu valoarea stocata n tabela temporar. Interogarea interioar poate contine n clauza WHERE i conditii complexe, formate prin utilizarea operatorilor logici (NOT, AND, OR) i a functiilor agregat (AVG, MAX, ).

"Sa se afiseze numele plantelor care au inaltimea minima" SELECT nume_planta FORM flori WHERE inaltime= (SELECT MIN(inaltime) FROM flori)

Subinterogri simple care returnez mai multe valori Principiul de construire a acestui tip de interogare imbricat utilizeaz n clauza WHERE conditii, care evaluate, genereaz o multime de valori. In aceast categorie intr operatorii (NOT) IN, (NOT) ANY, (NOT) ALL, (NOT) EXISTS.

1) "Care furnizori mai au inca de executat livrari?" SELECT nume_furnizor FROM furnizori WHERE cod_furnizor IN (SELECT cod_furnizor FROM comenzi GROUP BY cod_furnizor)

2) "Care furnizori, dintre furnizorii obisnuiti ai florariei, nu mai au nimic de livrat?" SELECT nume_furnizor FROM furnizori WHERE cod_furnizor NOT IN (SELECT cod_furnizor FROM comenzi GROUP BY cod_furnizor) A se observa ca cele doua interogari difera doar prin operatorul logic NOT. De asemenea se poate remarca faptul ca prima interogare aminteste de apartenenta din teoria multimilor iar a doua interogare corespunde operatiei minus (diferenta).

Daca versiunea SQL nu are un cuvant rezervat pentru operatia diferenta intre tabele, se poate construi aceasta operatie cu ajutorul predicatului NOT IN ca in exemplul de mai sus.

3) "Care furnizori au numarul maxim de comenzi de flori?" SELECT nume_furnizor FROM furnizori WHERE cod_furnizor IN (SELECT cod_furnizor FROM comenzi GROUP BY cod_furnizor HAVING COUNT(*)= (SELECT MAX(COUNT(cod_furnizor)) FROM comenzi GROUP BY cod_furnizor))

Subinterogri corelate n exemplele de pan acum, interogarea interioar era evaluat prima, dup care valoarea sau valorile rezultate erau utilizate de ctre clauza WHERE din interogarea exterioar. Exista i o alt forma de subinterogare i anume subinterogarea corelat, caz n care interogarea exterioar transmite repetat cte o valoare pentru interogarea interioar. De fiecare dat cnd este transmis o valoare, este evaluat interogarea interioar. Dac ambele interogri acceseaz acelasi tabel, trebuie asigurate alias-uri pentru fiecare referint la tabelul respectiv. Ambele interogri accesez tuple diferite din acelasi tabel n acelasi moment.

"Sa se afiseze culoarea, inaltimea i numele plantelor pentru plantele cu inaltimea maxima, ordonate dupa culoare" SELECT culoare, inaltime, nume_planta FROM flori f WHERE inaltime= (SELECT MAX(inaltime) FROM flori WHERE culoare=f.culoare) ORDER BY culoare

Operatorul EXISTS Operatorul EXISTS verific dac pentru fiecare tuplu al relatiei exist tuple care satisfac conditia interogrii interioare. In cazul n care exist asemenea tuple, EXISTS ia valoarea de adevr TRUE. Astfel, operatorul EXISTS permite specificarea mai multor atribute n interogarea interioar. Acest lucru este posibil deoarece nu se verific valoarea unui anumit atribut ca n cazurile anterioare, ci se genereaz o valoare de adevr (TRUE sau FALSE), dup cum exist sau nu exist o anumit valoare ntr-o relatie diferit de cea utilizat n interogarea exterioar. Ca i operatorii ANY i ALL, operatorul EXISTS apare in clauza WHERE.

"Care plante au un pret unitar egal sau mai mic cu cea mai ieftina planta de culoare alba?" SELECT nume_planta, pret_unitar, culoare FROM flori f WHERE NOT EXISTS (SELECT * FROM flori WHERE culoare='alb' AND pret_unitar>f.pret_unitar) Interogarea SELECT interioar defineste o tabela care contine acele tuple pentru care se verifica conditia din clauza WHERE interna. Daca nu exista nici o planta de culoare alba i care sa aiba pretul unitar mai mare decat pretul unitar din tuplul curent, conditia NOT EXISTS este evaluat la valoarea logica TRUE.

Se dau urmtoarele relaii cu schemele lor: -Scri (Nr_bloc, Scara, Lift) Apartamente(Nr_bloc,Scara,Apartament,Supraf aa,Cutii_potale, Nr_prize_tv) - Familii (Nr_mat, Nr_pers, Nr_pers_prez, Nr_chei) -Locatari (Nr_Mat, Nr_bloc, Scara, Etaj, Apartament,Nume)

S se exprime n SQL cererile: (tabel nominal cu locatarii de pe scara = 3 din bloc = 34) = R1 (tabel nominal cu locatarii de pe scara = 1 din bloc = 34) = R2 (tabel nominal cu locatarii de pe scara = 2 din bloc = 34) = R3 tabel nominal cu locatarii de pe scrile 1,2,3 ale blocului 34 lista apartamentelor cu suprafaa mai mare dect 50 mp tabel nominal cu persoanele carelocuiesc pe scara 3 bloc 34 i nu locuiesc i pe scara 1 a aceluiai bloc