Documente Academic
Documente Profesional
Documente Cultură
1 EVOLUŢIE ŞI PERFORMANŢE
Impactul SQL:
utilizatorii nespecialişti apreciază uşurinţa de înţelegere şi asimilare,
sunt mulţumiţi de posibilitatea de a consulta ei înşişi baza de date, fără
sprijin de specialitate.
pentru programatorii profesionişti SQL oferă comenzi puternice pentru
dezvoltarea de aplicaţii ce utilizează bazele de date.
Istoricul SQL: E.F.Codd sugerează crearea unui sub-limbaj universal pentru
gestionarea BD.
Prima realizare practică: 1974, la IBM, proiectul unui SGBD denumit
System/R.
1974 - o lucrare a lui Chamberlin şi Boyce foloseşte denumirea SEQUEL
(Structured English as QUEry Language) pentru un limbaj structurat de interogare.
1980 - Don Chamberlin “prescurtează” denumirea SEQUEL în SQL -
Structured Query Language (limbaj structurat de interogare), denumire sub care
s-a consacrat.
În anii următori limbajul a fost perfecţionat, ajungând la sfârşitul anilor ’90
cel mai răspândit limbaj de interogare a BDR.
Ştergerea unei tabele din baza de date se face cu DROP TABLE. Comanda
se utilizează de regulă pentru ştergerea tabelelor temporare, create pe parcursul
lucrului şi care nu trebuie păstrate în baza de date. Dacă am creat o tabelă
CLIENTI_CENTRE, necesară unor prelucrări deja încheiate, ştergerea ei se face
prin:
DROP TABLE CLIENTI_CENTRE
3.4 COMENZI PENTRU ACTUALIZAREA BAZELOR DE DATE
a) adăugarea de înregistrări,
b) ştergerea de înregistrări,
c) modificarea valorilor atributelor.
Exemplu 1
Să se adauge un film nou în tabela FILME.
INSERT
INTO FILME
VALUES (10109, “Die Hard 3", "Actiune", 2003, ”R2000”, 5.5)
Comanda DELETE se poate utiliza pentru a şterge toate liniile dintr-o tabelă.
Aşa cum se observă din format, clauza WHERE poate lipsi, deci comanda se aplică
tuturor înregistrărilor.
Utilitatea acestei comenzi vine atunci când ne permite ştergerea mai multor
înregistrări care îndeplinesc o condiţie.
Exemplu 3
Dacă firma noastră se reprofilează şi nu va mai închiria filme de
acţiune, acestea pot fi şterse din tabelă printr-o singură comandă:
DELETE
FROM FILME
WHERE Gen = “Actiune”
Modificarea se poate face pentru valorile unuia sau mai multor atribute dintr-
o tabelă specificată, în una sau mai multe înregistrări.
Exemplu 4
Decizia de a creşte preţul de închiriere al filmelor de acţiune cu 2 RON
presupune modificarea atributului PretInchir în toate înregistrările în
care avem filme de acest gen. Operaţiunea se poate realiza elegant
printr-un singur UPDATE:
UPDATE FILME
SET PretInchir = PretInchir + 2
WHERE Gen = “Actiune”
REZOLVARE:
Clauza WHERE apare între paranteze drepte deoarece poate lipsi, caz în care
toate liniile rezultate din tabelele consultate sunt incluse în tabela-
rezultat.
Exemplu 1
Se dă tabela SALARIATI.
Rezultatul:
Dacă scriem:
SELECT NrCentru, Marca, NumeSal
FROM SALARIATI
Obţinem o tabelă cu toţi salariaţii, de la toate centrele.
Exemplu 3
Care sunt filmele din anul 2020 pe care le avem?
SELECT *
FROM FILME
WHERE An = 2020
3.5.2 Precizări despre tipurile de date și scrierea de condiții de selecție
WHERE An >=2018
Dacă îl defineam de tip text, condiţia din exemplul de mai sus s-ar fi scris
WHERE An = "2020"
SELECT *
FROM COMENZI
WHERE Datacom = #10/20/2019#
Pentru datele de tip logic (tipul Yes/No) condiția este asumată prin
denumirea câmpului, folosind negația NOT pentru cazul când vrem valorile
NO/FALSE. Dacă vrem să vedem comenzile care au fost livrate scriem:
SELECT *
FROM COMENZI
WHERE Livrat
SELECT *
FROM COMENZI
WHERE NOT Livrat
3.5.3 Tabela-rezultat
In ACCESS se scrie:
SELECT * INTO PROD_DEP1
FROM PRODUSE
WHERE CodDep = 1
Exemplu 5
Să se afișeze valorile în Euro pentru facturi.
SELECT Nrfact, ValcuTVA/4.87 AS ValEUR
FROM Facturi
Exemplu 6
Să se afișeze codurile produselor comandate.
SELECT DISTINCT Codprod
FROM COMENZI
Se dă tabela
BURSIERI2020(CNP, Matricol, Medie, TipBursa, IBAN, Banca).
Care dintre ieșirile care au fost facturate au valoare mai mare de 1000
lei?
SELECT *
FROM IESIRI
WHERE Facturat AND Valoare>=1000
Care sunt facturile încasate prin bancă în ziua de 4 noiembrie?
SELECT *
FROM INCASARI
WHERE ModPlata = ”banca” AND DataInc = #11/4/2019#
Care sunt facturile pe care clientul cu codul 200 le-a plătit la livrare?
SELECT *
FROM FACTURI
WHERE Codcl = 200 AND TermenPl = 0
Exemplu 3
Care sunt filmele din 2006 din categoria “acţiune” sau “dramă”?
SELECT *
FROM FILME
WHERE An = 2006 AND (Gen = "Actiune" OR Gen = “Drama”)
Rezultat:
CodFilm Titlu Gen An PretInchir CodRegizor
10101 16 Blocks Actiune 2006 5.5 R1020
10204 Forrest Gump Drama 2006 7.5 R1028
Care sunt clienții din județele Arad și Timiș care sunt din prima
categorie (cod maxim 199)?
SELECT *
FROM CLIENTI
WHERE Cod <= 199 AND (Judet = "tm" OR Judet = “ar”)
Importanta parantezelor!!
Dacă s-ar scrie fără paranteze:
cei din TM care au cod mai mic de 199 SAU toti clientii din AR (pentru
ei nu se mai verifică și prima condiție...)
Exemplu 4
Care sunt filmele de acţiune apărute între 1997 şi 1999?
Fără operatorul BETWEEN am scrie:
SELECT *
FROM FILME
WHERE gen = "Actiune" AND An>=1997 AND An<=1999
Sau
SELECT *
FROM FILME
WHERE gen = "Actiune" AND (An=1997 OR An=1998 OR An=1999)
Care sunt facturile din perioada 1-7 noiembrie cu valoare între 200 și 500 lei?
SELECT *
FROM FACTURI
WHERE DataFact BETWEEN #11/1/2019# AND #11/7/2019#
AND ValFact BETWEEN 200 AND 500
Exemplu 5
Care sunt filmele în titlul cărora apare cuvântul “Man”?
SELECT *
FROM FILME
WHERE Titlu LIKE "*Man*"
Rezultat:
CodFilm Titlu Gen An PretInchir CodRegizor
10013 RainMan Drama 1988 5.5 R1019
10102 Man of the year Comedie 2006 5.5 R1019
SELECT *
FROM CLIENTI
WHERE Nume LIKE "A*"
De precizat că operatorul se poate utiliza atât pentru datele numerice (ca mai
sus), cât şi pentru texte sau date calendaristice. Spre exemplu, se poate căuta
valoarea lui CodActor într-o listă prin CodActor IN ("A118", "A119", "A120").
Care sunt comenzile clienților 200, 222 sau 300 care au cantitate mai mare de 50?
SELECT *
FROM COMENZI
WHERE Cantitate > 50 AND Codcl IN (200,222,300)
Exemplu 7
Să se afişeze lista filmelor pentru care NU s-a introdus anul lansării.
SELECT *
FROM FILME
WHERE An IS NULL
Observaţie:
Valoarea <null> nu se confundă cu valoarea zero (pentru câmpurile
numerice) sau cu "spaţiu" (pentru câmpurile de tip text). <null> înseamnă o
valoare necunoscută. A nu se înţelege că trebuie să scriem <null> când
introducem datele. Simpla necompletare a unui câmp va însemna că
respectivul are valoarea <null>.
SELECT *
FROM CLIENTI
WHERE email IS NOT NULL
3.7.2 Proiecţia
Prin proiecţie se reţin doar unele coloane din tabelele interogate. Coloanele
tabelei-rezultat sunt specificate în clauza SELECT separate prin virgulă.
Dacă se preiau toate coloanele, se foloseşte *. Dacă sunt mai multe tabele
(FILME şi REGIZORI), se va scrie:
Exemplu 9
Să se obţină lista filmelor pe care le avem, ordonate după anul
apariţiei.
SELECT Titlu, gen, an
FROM FILME
ORDER BY An
Rezultat:
Titlu Gen An
RainMan Drama 1988
The Firm Drama 1993
Leon Drama 1994
The Fifth Element Actiune 1997
Ronin Actiune 1998
Eyes Wide Shut Drama 1999
Cold Mountain Drama 2003
Meet the parents Comedie 2003
Meet the Fockers Comedie 2004
Moartea Dlui Lazarescu Drama 2005
The Interpreter Drama 2005
16 Blocks Actiune 2006
Failure to launch Comedie 2006
Man of the year Comedie 2006
Rezultat:
CodFilm Titlu Gen An PretInchir CodRegizor
10101 16 Blocks Actiune 2006 5.5 R1020
10103 Failure to launch Comedie 2006 5.5 R1021
10102 Man of the year Comedie 2006 5.5 R1019
Moartea domnului
10058 Lazarescu Drama 2005 3.5 R1017
10022 The Interpreter Drama 2005 5.5 R1015
10045 Meet the Fockers Comedie 2004 5.5 R1012
10077 Meet the parents Comedie 2003 5.5 R1011
10021 Cold Mountain Drama 2003 5.5 R1014
10023 Eyes Wide Shut Drama 1999 3.5 R1015
10011 Ronin Actiune 1998 3.5 R1011
10018 The Fifth Element Actiune 1997 3.5 R1013
10099 Leon Drama 1994 5.5 R1013
10055 The Firm Drama 1993 3.5 R1015
10013 RainMan Drama 1988 5.5 R1019
SELECT *
FROM COMENZI
WHERE CODCL = 100
ORDER BY datacom DESCENDING
TESTUL DE LA CURS
Se dă tabela FILME(CodFilm, Titlu, Gen, An, PretInchir, CodRegizor)
1. Să se afișeze lista filmelor mai vechi de anul 2000 pentru care nu se cunoaște
regizorul.
SELECT *
FROM FILME
WHERE AN<=2000 AND CODREGIZOR IS NULL
2. Să se afișeze titlul și anul apariției pentru filme din genul comedie, din anii 2010,
2012, 2014, ordonate după an descrescător.
SELECT titlu, an
FROM FILME
WHERE AN IN (2010, 2012, 2014) AND GEN="comedie"
ORDER BY an DESCENDING
3. Să se afișeze lista filmelor de genul dramă sau acțiune, al căror titlu conține
”batman”, ordonate după titlu.
SELECT *
FROM FILME
WHERE GEN IN ("actiune","drama") AND TITLU LIKE "*batman*"
ORDER BY titlu
Exemplu 11
Care sunt salariaţii care lucrează 40 de ore pe săptămână?
SELECT NumeSal, NrCentru
FROM SALARIATI INNER JOIN ORELUCRATE
ON SALARIATI.Marca = ORELUCRATE.Marca
WHERE OrePeSapt=40
Rezultat:
Numesal NrCentru
Albu Petre T001
Verdeţ Ion T002
George Crina T002
Fekete Iulian T004
Negru Iulia T004
Să se obțină o listă cu clienții care au comandat produsele cu cod 10 și 11 (nume,
localitate, data comenzii, cantitate), cu ordonare după dată și client.
Să se obțină o listă cu clienții din județul Arad care au comandat cantități între
100 și 200 (nume, localitate, cod produs, cantitate) sortați alfabetic.
Să se obțină o listă cu comenzile la produse din depozitul 2 (nr comanda, data, cod
produs, cantitate, valoare comanda).
SELECT nrcom, datacom, codprodus,
cantitate, cantitate*pretlista
FROM COMENZI INNER JOIN PRODUSE ON
COMENZI.codprodus = PRODUSE.codprod
WHERE coddep = 2
Exemplu 12
Care sunt salariaţii din centrele din Timişoara care lucrează 40 de ore pe
săptămână?
SELECT NumeSal, SALARIATI.NrCentru, Oras
FROM (SALARIATI INNER JOIN ORELUCRATE
ON SALARIATI.Marca = ORELUCRATE.Marca)
INNER JOIN CENTRE ON SALARIATI.NrCentru = CENTRE.NrCentru
WHERE Oras = ”Timisoara” AND OrePeSapt = 40
Rezultat:
Nume NrCentru Oras
Albu Petre T001 Timisoara
Verdeţ Ion T002 Timisoara
George Crina T002 Timisoara
Exemplu 13
Care sunt personajele şi actorii din filmele apărute în 2003?
SELECT Titlu, Personaj, Nume
FROM (FILME INNER JOIN ROLURI ON FILME.CodFilm = ROLURI.CodFilm)
INNER JOIN ACTORI ON ROLURI.CodActor = ACTORI.CodActor
WHERE An = 2003
Rezultat:
Titlu Personaj Nume
Meet the parents Jack Byrnes Robert De Niro
Cold Mountain Sara Natalie Portman
Cold Mountain Ada Monroe Nicole Kidman
Sub-consultări SQL
Exemplu 1
Care sunt salariaţii care lucrează în acelaşi centru de închiriere cu
salariatul Nica Ioana?
SELECT *
FROM SALARIATI
WHERE NrCentru IN
(SELECT NrCentru
FROM SALARIATI
WHERE Nume=”Nica Ioana”)
Sub-consultarea
SELECT NrCentru
FROM SALARIATI
WHERE Nume=”Nica Ioana”
are ca rezultat o tabelă alcătuită dintr-o singură coloană (NrCentru) şi o
singură linie ce conţine valoarea atributului NrCentru pentru salariatul cu numele
Nica Ioana:
NrCentru
T001
Exemplu 2
Care sunt actorii care au jucat în aceleaşi filme cu Jean Reno?
SELECT NumeActor
FROM ROLURI INNER JOIN ACTORI ON
ROLURI.CodActor = ACTORI.CodActor
WHERE CodFilm IN
(SELECT CodFilm
FROM ROLURI INNER JOIN ACTORI ON
ROLURI.CodActor = ACTORI.CodActor
WHERE Nume=”Jean Reno”)
Rezolvare:
Nume
Robert DeNiro
Jean Reno
Natalie Portman
Gary Oldman
Rezolvarea exemplului de mai sus a presupus realizarea de joncţiuni în cadrul
sub-consultării. O altă variantă de rezolvare este şi:
SELECT Nume
FROM ACTORI
WHERE CodActor IN
(SELECT CodActor
FROM ROLURI
WHERE CodFilm IN
(SELECT CodFilm FROM ROLURI
WHERE CodActor IN
(SELECT CodActor FROM ACTORI
WHERE Nume=”Jean Reno”)))
Am ilustrat modul în care pot fi înlănţuite patru fraze SELECT. Această soluţie
"merge" în ACCESS, nu şi în alte SGBD-uri, precum Visual FoxPro, unde este posibil
doar un nivel de sub-consultare.
Se poate reţine, ca regulă generală, că aproape orice consultare poate fi
redactată în mai multe moduri, în funcţie de experienţa şi imaginaţia celui care
o formulează.
Rezultat:
Nr_Salariati
7
Rezultat:
Cate_Filme
6
Exemplu 3
Care este numărul total de ore lucrate pe săptămână la toate
centrele?
SELECT SUM(OrePeSapt) AS Total_Ore
FROM ORELUCRATE
Rezultat:
Total_Ore
270
Exemplu 4
Care este numărul total de ore lucrate săptămânal în centrele din
Timişoara?
SELECT SUM (OrePeSapt) AS Total_Ore_TM
FROM ORELUCRATE INNER JOIN CENTRE
ON ORELUCRATE.NrCentru = CENTRE.NrCentru
WHERE Oras = “Timisoara”
Rezultat:
Total_Ore_TM
190
Care sunt cea mai mică și cea mai mare cantitate comandată?
Care este valoarea cea mai mare a facturii clienților din județul Arad?
Se execută mai întâi SELECT din paranteză și dă valoarea 1988, apoi se aleg
titlu și an din tabela FILME:
Titlu An
RainMan 1988
Care este clientul care are valoarea cea mai mare a facturii?
SELECT nume
FROM CLIENTI
WHERE cod IN
(SELECT codcl FROM FACTURI WHERE
VALCUTVA IN (SELECT MAX(valcutva) FROM FACTURI)
Rezultatul unei fraze SELECT ce conţine clauza GROUP BY este o tabelă care
va fi obţinută prin regruparea tuturor liniilor din tabelele enumerate în FROM, care
prezintă o aceeaşi valoare pentru o coloană.
Exemplu 1
Care este numărul de filme disponibile pentru fiecare gen?
SELECT Gen, COUNT(CodFilm) As NrFilme
FROM FILME
GROUP BY Gen
Rezultat:
Gen NrFilme
Comedie 4
Drama 7
Actiune 3
codcl TotalValfact
100 2754
101 3143
..... ..........
Exemplu 2
Care este numărul de filme pentru fiecare regizor ?
SELECT NumeRegizor, COUNT(CodFilm) AS NrFilme
FROM FILME INNER JOIN REGIZORI ON
FILME.CodRegizor=REGIZORI.CodRegizor
GROUP BY FILME.CodRegizor
ORDER BY NumeRegizor
Rezultat:
NumeRegizor NrFilme
Anthony Minghella 1
Barry Levinson 2
Cristi Puiu 1
Jay Roach 1
John Frankenheimer 2
Luc Besson 2
Richard Donner 1
Sydney Pollack 3
Tom Dey 1
Clauza HAVING permite introducerea unor restricţii asupra grupurilor de
înregistrări, astfel că în tabela-rezultat sunt incluse doar grupurile care satisfac
condiţia specificată.
Clauza HAVING se foloseşte doar împreună cu o clauză GROUP BY (Este ca
o clauză WHERE aplicată grupurilor).
Exemplu 3
Care sunt regizorii care au mai mult de 2 filme în baza noastră de
date?
SELECT NumeRegizor, COUNT(CodFilm) AS NrFilme
FROM FILME INNER JOIN REGIZORI ON
FILME.CodRegizor=REGIZORI.CodRegizor
GROUP BY FILME.CodRegizor
ORDER BY NumeRegizor
HAVING COUNT(CodFilm)>=2
Rezultat:
NumeRegizor NrFilme
Barry Levinson 2
John Frankenheimer 2
Luc Besson 2
Sydney Pollack 3
SELECT COUNT(*)
FROM FILME
WHERE GEN=”COMEDIE” AND AN<2000