Mysql
Mysql
1. Introducere
MySQL este unul dintre cele mai populare sisteme de gestiune de baze de date (SGBD) in regim OpenSource.
Producatorul sau se numeste MySQL AB si este o companie a carei principala activitate consta in oferirea de servicii legate de
acest SGBD.
• Este un SGBD.
Asigura gestiunea unei colectii structurate de date.
• Este un SGBD relational.
Datele sunt organizate in tabele. Intre tabele sunt stabilite relatii si constrangeri de integritate. Pentru gestiunea datelor
foloseste limbajul SQL (Structured Query Language) care este un standard in acest domeniu.
• Este un sistem client-server.
Serverul de baze de date este separat logic si deseori fizic (pe calculatoare diferite) de programele client care asigura
interfata operatiilor cu baza de date. Serverul MySQL suporta o paleta larga de programe client, scrise in diverse limbaje
• de programare.
Crearea unei baze de date corespunde crearii unui director in care vor fi pastrate elementele specifice cum ar fi: tabele,
indecsi, jurnale etc. Daca deja exista o baza de date cu numele specificat se va da un mesaj de eroare.
Pentru selectarea unei baze de date se va folosi comanda USE. Prin aceasta se stabileste baza de date in contextul
careia se vor executa interogarile ulterioare. Ea se va numi baza de date activa.
Chiar daca o singura baza de date poate fi activa la un moment dat, o interogare poate referi tabele si din alte baze de
date prin utilizarea prefixarii cu numele bazei de date respective (ex. db2.tabela5).
Exemplu:
2. Tipuri de date
1
2.1. Tipuri de date numerice
1. DATE
Data calendaristica. Intervalul de valori posibile este ['1000-01-01'..'9999-12-31']. Stocarea/afisarea se face implicit in
formatul 'YYYY-MM-DD' (an-luna-zi).
2. DATETIME
Combinatie de data calendaristica si timp. Intervalul de valori posibile este ['1000-01-01 00:00:00'..'9999-12-31 23:59:59'].
Stocarea/afisarea se face implicit in formatul 'YYYY-MM-DD HH:MM:SS' (an-luna-zi ora:minut:secunda).
3. TIMESTAMP [(M)]
Moment de timp. Include si data calendaristica. Este util la inregistrarea efectuarii unor operatii gen inserare sau
modificare pentru ca retine implicit data efectuarii ultimei operatii. Doar prima coloana de acest tip din tabela in care se
face modificarea va fi actualizata automat! Intervalul de valori posibile este ['1970-01-01 00:00:00'..'2037-01-01 00:00:00'].
MySQL afiseaza valorile TIMESTAMP in format YYYYMMDDHHMMSS, YYMMDDHHMMSS, YYYYMMDD sau YYMMDD
dupa cum M este 14 (sau lipseste), 12, 8 sau 6. Parametrul M nu influenteza insa reprezentarea interna a datelor la
stocare.
4. TIME
Moment de timp. Intervalul de valori posibile este [-838:59:59'..'838:59:59']. Reprezentarea este in format 'HH:MM:SS'
(ora:minut:secunda). Motivul pentru care ora nu este limitata la intervalul [0..24] esta ca acest tip poate fi folosit si pentru a
retine intervale de timp intre doua evenimente. Tot din acest motiv ora poate fi si negativa.
5. YEAR [(2|4)]
An calendaristic pe 2 sau 4 cifre. Intervalul de valori posibile este [1901..2155] pentru 4 cifre, respectiv [1970..2069]
pentru 2 cifre (70-99..00-69).
Se folosesc pentru a retine obiecte binare (BLOB) de mari dimensiuni (ex. imagini, secvente audio sau video) sau pentru a retine
texte de dimensiune in general mai mare de 255 caractere (TEXT). La comparatia campurilor tip TEXT nu se va tine cont de tipul
caracterelor (mari/mici).
1. TINYBLOB
TINYTEXT
Valori BLOB, respectiv TEXT cu lungime de max. 255 elemente.
2. BLOB
TEXT
Valori BLOB, respectiv TEXT cu lungime de max. 65535 (64 KB) elemente.
3. MEDIUMBLOB
MEDIUMTEXT
Valori BLOB, respectiv TEXT cu lungime de max. 16777215 (16 MB) elemente.
4. LONGBLOB
LONGTEXT
Valori BLOB, respectiv TEXT cu lungime de max. 4294967295 (4 TB) elemente.
1. ENUM ('value1','value2',...)
Enumerare de elemente tip sir de caracter. Un obiect de acest tip poate avea la un moment dat o singura valoare dintre
cele enumerate sau valoarea NULL. Valoarea " " (sir vid) este considerata valoare de eroare. Un tip enumerare poate
defini maxim 65535 de valori distincte.
2. SET ('value1','value2',...)
Multime de elemente tip sir de caracter. Un obiect de acest tip poate contine la un moment dat mai multe valori distincte
dintre cele definite sau poate fi gol (nu contine nici o valoare). Un tip multime poate defini maxim 65 de valori membru.
3.1. Constante
3
o \\ Caracterul \.
o \% Caracterul '%'. Se poate folosi pentru a cauta caracterul %, in conditiile in care acest caracter este folosit in
expresii regulate (subiectul va fi detaliat ulterior).
o \_ Caracterul _. Se poate folosi pentru a cauta caracterul _, in conditiile in care acest caracter este folosit in
expresii regulate (subiectul va fi detaliat ulterior).
Rulati secventele:
Activitate 1
mysql> SELECT 'hello', '"hello"', '""hello""', 'hel''lo', '\'hello' ;
mysql> SELECT "hello", "'hello'", "''hello''", "hel""lo", "\"hello" ;
• Constantele intregi sunt reprezentate printr-un sir de cifre zecimale. Constantele reale contin semnul '.' pentru
specificarea partii zecimale. Ambele tipuri pot fi precedate de semnul '-' pentru a indica numere negative.
Ex:
13534
342.3453
• Constanta NULL este folosita cu semnificatia "nici o valoare". Se face diferenta intre NULL si numarul 0 sau sirul vid "".
3.2. Identificatori
Numele pentru baza de date, tabele, coloane, indecsi sau alias-uri trebuie sa indeplineasca conditiile normale pentru identificatori
in limabje de programare: sa fie o combinatie de litere, cifre si semne grafice care incep cu o litera. In plus mySQL impune:
Referirea la o coloana in cadrul unei interogari se poate face in mai multe moduri, functie de contextul existent:
Identificatorii pot fi scrisi in general cu orice combinatie de litere mari sau mici. Pentru numele bazei de date si cel al tabelelor
unele, implementari impun respectarea tipului de caractere folosit la definirea elementelor respective. Ca si regula generala, este
bine sa se pastreze o conventie de notare care sa nu fie schimbata de la o interogare la alta. O regula simpla este sa se scrie
comenzile SQL cu litere mari si identificatorii definiti de utilizator cu litere mici.
3.3. Comentarii
MySQL suporta trei tipuri de comentarii prin care se poate explica codul. Ele sunt:
4
Rulati secventele:
Sunt folosite pentru a schimba ordinea de evaluare in interiorul expresiilor. Parantezele folosite sunt doar paranteze rotunde.
Rulati secventele:
Activitate 3
mysql> SELECT 1+2*3;
mysql> SELECT (1+2)*3;
Operatorii aritmetici opereaza asupra numerelor intregi cu precizia BIGINT (pe 64 biti). Sunt disponibili urmatorii operatori:
• + pentru adunare;
• - pentru scadere;
• * pentru inmultire;
• / pentru impartire; daca se imparte la 0 rezultatul va fi NULL;
Rulati secventele:
• NOT
! - Negatie logica. Intoarce 1 daca argumentul este 0, altfel intoarce 0. Exceptie: NOT NULL intoarce NULL.
• OR
|| - SAU logic. Intoarce 1 daca cel putin un argument nu este 0 sau NULL.
• AND
&& - SI logic. Intoarce 0 sau NULL daca cel putin un argument este 0 sau NULL, altfel intoarce 1.
Rulati secventele:
5
Operatorii de comparare returneaza 1 pentru adevarat, 0 pentru fals si NULL daca nu se poate efectua comparatia.
Ei pot compara atat numere cat si siruri de caractere. La compararea unui numar cu un sir se incearca transformarea sirului in
numarul pe care il contine.
La compararea a doua siruri nu se va tine cont de litere mari/mici.
Rulati secventele:
• ASCII(str) - intoarce codul ASCII al caracterului de pe pozitia 1 din sir. Daca sirul este vid intoarce 0.
• CONV(N, from_base, to_base) - converteste numarul N considerat in baza from_base in valoarea sa in baza to_base.
• CHAR(N,...) - converteste sirul de numere primite intr-un sir de caractere ale caror coduri ASCII sunt egale cu cele din
sirul initial.
• CONCAT(str1,str2,...) - concateneaza sirurile primite ca argument, returnand sirul rezultat.
• LENGTH(str) - intoarce lungimea (numarul de caractere) a sirului primit ca si argument.
• LOCATE(substr,str)
POSITION(substr IN str) - cauta prima aparitie a sirului substr in sirul str. Daca il gaseste returneaza pozitia, daca nu,
returneaza 0.
• LEFT(str,len) - intoarce un sir format din primele len caractere din sirul dat.
• RIGHT(str,len) - intoarce un sir format din ultimele len caractere din sirul dat.
• SUBSTRING(str,pos,len)
MID(str,pos,len) - intorc subsirul de pe pozitia pos, de lungime len caractere din sirul str.
• SUBSTRING_INDEX(str,delim,count) - intoarce subsirul pana la count aparitii ale caracterului delimitator delim. Daca
delim este pozitiv intoarce prima parte a sirului, daca este negativ, ultima parte.
• LTRIM(str)
RTRIM(str)
TRIM(str) - intoarce sirul str fara spatiile de la inceput (LTRIM), sfarsit (RTRIM) sau din ambele parti (TRIM).
• SPACE(N) - intoarce un sir format din N spatii.
• LOWER(str)
UPPER(str) - intorc sirul str cu toate caracterele convertite la litere mici, respectiv litere mari.
6
• sir (NOT) LIKE tipar - compara sirul sir cu tiparul dat. Intoarce adevarat (1) daca se potrivesc. Tiparele pot include
caracterele speciale: '_' care se potriveste cu orice caracter si '%' care poate inlocui orice secventa de 0 sau mai multe
caractere. Ex. 'ana' LIKE 'an_', 'ana' LIKE 'a%', 'ana' NOT LIKE 'a%z'.
Rulati secventele:
Rulati secventele:
• DAYOFWEEK(date) - indexul zilei din spatamana al datei specificate (1=duminica, 2=luni etc.)
• DAYOFYEAR(date) - numarul zilei din an pentru data specificata
• DAYNAME(date) - numele (in engleza) al zilei din data specificata
• MONTHNAME(date) - numele (in engleza) al lunii din data specificata
• YEAR(date) - extrage anul din data specificata
• HOUR(time) - extrage ora din timpul precizat
• MINUTE(time) - extrage minutul din timpul precizat
• SECOND(time) - extrage secunda din timpul precizat
• CURDATE() - intoarce data curenta in format 'YYYY-MM-DD'
• CURTIME() - intoarce ora curenta in format 'HH:MM:SS'
7
• NOW()
SYSDATE() - intoarce data si ora curenta in format 'YYYY-MM-DD HH:MM:SS'
• SEC_TO_TIME(seconds) - intoarce timpul in format 'HH:MM:SS' reprezentat de numarul de secunde specificate
• TIME_TO_SEC(time) -converteste timpul specificat in numar de secunde scurse de la ora 00:00:00
Rulati secventele:
Rulati secventele:
Activitate 10
mysql> SELECT DATABASE(), USER(), VERSION() ;
mysql> SELECT FORMAT(345674355.35,3), PASSWORD("parola") ;
Datele rezultate din procesul de analiza a problemei ce trebuie implementata se impart in tabele prin procesul de normalizare. In
acest fel o baza de date va fi formata dintr-o colectie de tabele. Pentru a crea o tabela se va utiliza comanda SQL CREATE
TABLE.
• TEMPORARY - specifica crearea unei tabele temporare care va fi stearsa automat la inchiderea conexiunii in care a fost
creata; doua conexiuni pot crea doua tabele temporare cu aceleasi nume, ele nu vor interfera.
• IF NOT EXISTS - inhiba mesajul de eroare care se genereaza daca la incercarea de a crea o tabela care mai exista.
• create_definition - pentru definirea coloanelor este un sir de tipul:
col_name type [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT] [PRIMARY KEY]
o col_name - nume coloana
o type - tip coloana (vezi sectiunea 1)
o NOT NULL - nu se permit valori NULL in acest camp (campul trebuie completat in orice situatie)
o NULL - permite valori NULL in camp (optiune implicita daca nu se specifica nimic)
o DEFAULT default_value - completeaza campul lasat liber cu valoarea implicita default_value
o AUTO_INCREMENT - daca nu se insereaza nimic in camp, se va genera automat o valoare mai mare cu o
unitate fata de cea mai mare valoare din acel camp. Poate fi specificata o singura coloana cu acest parametru
intr-o tabela. Coloanele specificate astfel trebuie indexate.
o PRIMARY KEY - specifica cheia primara pentru tabela. Un singur camp din tabela poate avea acest parametru.
Coloana declarata ca si cheie primara este indexata automat. Daca tabela are cheia primara formata din mai
multe campuri, aceasta va trebui specificata separat, pe post de camp suplimentar, cu sintaxa "primary key
(camp1, camp2 ...)".
• create_definition - pentru definirea indexilor are forma:
INDEX (coloana1,...)
8
Parametrul IF EXISTS va inhiba mesajul de eroare care apare daca tabela nu exista.
Selectati cu ajutorul comenzii USE baza de date BANCA creata la Tema 2.2. Creati o tabela Deponent ruland comanda:
Comanda INSERT permite inserarea (adaugarea) de noi inregistrari (randuri) intr-o tabela.
Deoarece sistemul mySQL este pur relational, nu exista nici o diferenta intre inserarea de noi date sau adaugarea lor. In ambele
situatii, locul in care se face adaugarea nu este precizat, nefiind relevant. La sistemele care nu sunt pur relationale (cum este
dBase sau FoxPro) operatia de adaugare semnifica adaugarea la sfarsitul unei tabele, pe cand insertia inseamna inserarea intre
alte doua inregistrari existente.
• LOW_PRIORITY - se foloseste pentru a intarzia scrierea efectiva a datelor in tabela pana cand alti utilizatori nu mai citesc
date din tabela. Acest lucru avantajeaza citirea dar intarzie, semnificativ pentru o tabela foarte utilizata, scrierea. Efectul
este blocarea executiei pana cand se reuseste scrierea efectiva.
• DELAYED - are actiune opusa parametrului precedent. Inregistrarea care trebuie adaugata este pusa intr-o coada de
asteptare pe server si controlul revine la client, ca si cum scrierea ar fi fost facuta efectiv. Avantajul consta in timpul mic de
executie a comenzii INSERT pe o tabela utilizata intensiv. Dezavantajul consta in incarcarea serverului cu o operatie in
plus si in pierderea datelor daca serverul se opreste neasteptat. Din aceasta cauza parametrul este folosit doar cand este
cu adevarat necesar.
• IGNORE - este util daca se insereaza mai multe inregistrari simultan (in acest caz lista de dupa VALUES va contine mai
multe seturi de date in paranteze, departite prin virgula). In mod obisnuit, MySQL raporteaza eroare si nu executa
comanda care incearca adaugarea a cel putin unei inregistrari care duplica cheia primara sau campuri cu valori unice.
Prin folosirea parametrului IGNORE inregistrarile gresite sunt ignorate, dar restul sunt adaugate fara raportarea unei erori.
Dupa executia comenzii se va raporta doar numarul de inregistrari a caror adaugare a reusit.
• INTO - este optional, se foloseste pentru compatibilitate cu alte sisteme SQL. Datorita claritatii mai mari a interogarii se
prefera totusi utilizarea lui.
• tbl_nume - specifica numele tabelei unde se adauga inregistrarile.
• (col_nume,...) - este o lista de coloane care specifica ordinea in care se vor adauga datele in tabela. Prin aceasta se pot
insera doar datele considerate esentiale, restul primind valorile implicite specificate la declararea tabelei. Daca lista
lipseste, setul de date furnizat trebuie sa aiba valori pentru toate campurile, in ordinea din declararea tabelei.
• VALUES - specifica seturile de date (inregistrarile) care se vor adauga in tabela.
9
• (expresie, ...),(...),... - fiecare paranteza specifica datele unei inregistrari ce va fi adaugata. Ele trebuie sa respecte
numarul si ordinea coloanelor de la declararea tabelei sau, daca e specificat, numarul si ordinea campurilor din lisata de
coloane (col_nume,...) prezentata anterior.
O sintaxa introdusa o data cu versiunea 3.22.10 permite specificarea explicita a corespondentei intre coloane si valorile inserate:
O a treia sintaxa permite adugarea automata a inregistrarilor prin selectia lor din alte tabele:
Optiunea SELECT va fi discutata pe larg in capitolul urmator. In principiu trebuie retinute totusi cateva limitari:
Deponent
nr_buletin char(8) NOT NULL PRIMARY KEY
cnp char(13) NOT NULL
nume char(24) NOT NULL
prenume char(24) NOT NULL
datan date
oras char(24) DEFAULT 'Timisoara'
adresa char(32)
telefon char(9)
Conturi
nr_cont char(6) NOT NULL PRIMARY KEY
nr_buletin char(8) NOT NULL
tip_cont char(3) DEFAULT 'Lei'
termen_depozit int(3) DEFAULT 0
sold int DEFAULT 0
Operatii
nr_cont char(6) NOT NULL
suma int
data timestamp
10
('TM832312', '1112282568441','Florin','Marasescu'),
('TM436613', '0090976761426','Ana','Tipatescu');
mysql> INSERT INTO Deponent
SET nume='Gerogescu', prenume='Henrieta',
nr_buletin='GL654321', cnp='0111166163476',
oras='Galati';
mysql> SELECT * FROM Deponent;
• LOW_PRIORITY - intarzie executia comenzii UPDATE pana cand nici un alt client nu mai citeste din tabela. Are acelasi
efect ca si in cazul comenzii INSERT.
• IGNORE - nu se intrerupe executia in cazul in care se duplica chei unice la actualizare. Inregistrarile care cauzeaza erori
sunt pur si simplu ignorate.
• tbl_nume - nume tabela unde are loc actualizarea
• SET col_nume1=expr1,col_nume2=expr2,... - indica acele coloane care sunt modificate si noile lor valori. Expresiile de
actualizare pot cuprinde vechile valori ale campurilor de actualizat.
• WHERE conditie_de_actualizare - indica acele coloane care sunt actualizate, si anume doar cele pentru care
conditie_de_actualizare are valoarea adevarat. Daca clauza WHERE lipseste, vor fi actualizate toate inregistrarile.
Considerand tabelele bazei de date Banca si datele adaugate in cadrul activitatii anterioare, se vor exemplifica urmatoarele
actualizari:
Rulati actualizarile:
11
Sintaxa comazii DELETE este:
• LOW_PRIORITY - intarzie executia comenzii DELETE pana cand nici un client nu mai citeste din tabela. Are acelasi efect
ca si in cazul comenzii INSERT.
• FROM tbl_nume - specifica tabela de unde se sterg inregistrari.
• WHERE conditie_de_stergere - specifica inregistrarile care vor fi sterse, si anume cele care indeplinesc conditia logica
precizata. Atentie! Daca clauza WHERE este omisa se vor sterge toate inregistrarile din tabela.
Considerand tabelele bazei de date Banca si datele adaugate in cadrul activitatii anterioare, se vor exemplifica urmatoarele
stergeri:
Rulati secventele:
8. Interogarea datelor
Comanda SELECT este cea mai utilizata comanda SQL. Ea permite atat regasirea si vizualizarea datelor din tabelele bazei de
date cat si calcularea unor expresii care nu au legatura cu datele din tabele.
Sintaxa comenzii SELECT pentru calcularea valorii unor expresii este foarte simpla si a fost deja folosita in capitolele anterioare:
SELECT expresie;
SELECT [SQL_BUFFER_RESULT]
[HIGH_PRIORITY]
[DISTINCT | ALL]
expresie_de_selectie,...
[INTO {OUTFILE | DUMPFILE} 'nume_fisier']
[FROM referinte_tabele
[WHERE conditie_selectie]
[ORDER BY {intreg_pozitiv | nume_col | formula} [ASC | DESC] ,...]
Parametrii din paranteze drepte sunt optionali. Cei din acolade si despartiti prin '|' sunt obligatorii dar mutual exclusivi (doar unul
poate apare).
Ei au urmatoarea semnificatie:
12
• SQL_BUFFER_RESULT - se foloseste pentru a forta serverul sa creeze o tabela temporara cu rezultatul interogarii. Acest
lucru este util in cazul in care tabela interogata este utilizata intensiv in retea si se doreste deblocarea rapida a ei pentru
accesul altor clienti. In mod obisnuit nu este necesar.
• HIGH_PRIORITY - da prioritate interogarii curente fata de alte interogari INSERT sau UPDATE aflate in coada de
asteptare pentru acea tabela.
• DISTINCT - Permite eliminarea randurilor duplicate din selectie.
• ALL - Rezultatul selectiei va cuprinde si randuri duplicate. Daca nu se specifica nici DISTINCT, nici ALL, implicit se
considera ALL.
• expresie_de_selectie - expresia de selectie poate cuprinde referinte la coloane sau la functii aplicate asupra acestora.
Un caz special il reprezinta caracterul * care semnifica includerea tuturor coloanelor din tabela in rezultat.
• INTO {OUTFILE | DUMPFILE} 'nume_fisier' - permite salvarea rezultatului unei interogari sub forma unui fisier text.
Fisierul va fi creat pe server (trebuie sa nu existe), implicit in directorul bazei de date. Optiunea OUTFILE specifica
salvarea tuturor randurilor rezultatului formatate pe coloane, pe cand DUMPFILE permite salvarea unui singur rand fara
formatare. DUMPFILE este util pentru a salva campuri de tip BLOB (imagini, sune, video).
• FROM referinte_tabele - specifica tabela sau tabelele din care se selecteaza datele. In cazul in care referinta cuprinde
mai multe tabele operatia este una de JOIN.
• WHERE conditie_selectie - specifica conditia de includere a datelor in selectie. Permite selectia doar a datelor care
intereseaza la un moment dat. In cazul operatiunii de JOIN aici se vor adauga si constrangerile date de relatiile dintre
tabele. Conditia de selectie consta dintr-o expresie logica simpla sau complexa care poate cuprinde functiile prezentate in
capitolul 3.
• ORDER BY {intreg_pozitiv | nume_col | formula} [ASC | DESC], ... - permite ordonarea rezultatului dupa anumite
coloane sau formule. Daca se specifica o lista de numere, acestea vor fi interpretate ca numere de ordine a coloanelor
specificate in SELECT (incepand cu 1). Ordonarea se face dupa prima coloana din lista. In cazul in care doua inregistari
au aceiasi valoare pentru coloana respectiva se va lua in considerare a doua coloana din lista (daca este specificata) etc.
Parametrii ASC si DESC specifica ordonarea crescatoare, respectiv descrescatoare a inregistrarilor in rezultat.
Rulati secventele:
Conditiile de selectie permit regasirea datelor necesare intr-un anumit context. La scrierea acestor conditii vor putea fi folosie
functiile prezentate in Capitolul 3. De asemenea, la folosirea operatorilor de comparatie se va tine seama de observatiile facute
acolo.
Activitatea urmatoare prezinta diverse moduri de scriere a unor conditii de selectie INSERT.
13
mysql> SELECT * FROM Deponent
WHERE prenume='victor' and datan>='1960-01-01';
# Selectia deponentilor nascuti intre 1960 si 1970
mysql> SELECT * FROM Deponent
WHERE Year(datan)>=1960 and Year(datan)<=1970;
Rulati secventele:
Pentru a simplifica scrierea instructiunilor se pot folosi denumiri prescurtate, numite alias-uri (porecle). Ele pot fi folosite atat
pentru a desemna tabele cat si coloane.
O utilitate deosebita o au in cazul combinarii datelor din mai multe baze de date, pentru a inlocui nume de tipul
nume_baza_de_date2.nume_tabela_1.nume_coloana_3, in cazul coloanelor calculate sau in cazul operatiilor de JOIN (vor fi
discutate in capitolul urmator).
Dupa cum se observa, alias-urile definite pentru tabele pot fi folosite in partea de specificare a coloanelor, iar alias-urile coloanelor
pot fi folosite in clauze ORDER BY sau HAVING (va fi discutata in capitolul urmator).
14
FROM Deponent d
ORDER BY o, num;
# Alias pentru camp calculat
mysql> SELECT nume, prenume, Year(datan) AS an FROM Deponent
ORDER BY an;
Comanda SELECT in forma studiata in capitolul anterior permite efectuarea operatiei de selectare a datelor dintr-o singura tabela
(implementeaza operatorul SELECT din algebra relationala).
Limbajul SQL foloseste insa tot comanda SELECT pentru implementarea operatorului JOIN. Acest operator este definit de
algebra relationala pentru a permite colectarea datelor din tabelele aflate in legaturi relationale.
Folosirea comenzii SELECT pentru a face JOIN presupune specificarea in clauza FROM a tabelelor de unde se preiau datele si,
in lista de proiectie, a campurilor care vor face parte din rezultat.
In acest caz forma generala a instructiunii SELECT este:
SELECT lista_campuri
FROM lista_tabele
WHERE conditii_join AND conditii_selectie
ORDER BY ...
 ...
• lista_campuri - specifica acele campuri care vor face parte din rezultat. Aceste campuri pot fi din oricare tabela
specificata in clauza FROM. In situatia in care un camp din rezultat apare sub acelasi nume in doua sau mai multe tabele
el trebuie prefixat cu tabela din care se extrage. In locul numelui tabelei se prefera de obicei folosirea unui alias.
• lista_tabele - specifica tabelele din care se vor aduna datele. Unele tabele de aici pot fi doar tabele de legatura intre alte
tabele, ele neavand nici un camp selectat in rezultat. Functie de tipul de operatie JOIN dorit, lista_tabele poate fi doar o
lista de nume despartite prin virgula sau poate avea o forma mai execta, dupa cum se va preciza in sectiunea urmatoare.
• conditii_join - specifica conditiile relationale care leaga tabelele. Ele sunt de obicei de forma
tabela1.cheie_externa=tabela2.cheie_primara AND .... Daca o legatura lipseste sau este pusa gresit, rezultatul va fi de
obiecei un produs cartezian intre tabele (toate combinatiile posibile intre inregistrari, fara a tine seama de legaturile
relationale).
• conditii_selectie - specifica conditiile de filtrare a rezultatului dupa adunarea datelor din tabele.
Activitate 1 Adaugati la tabela Operatii cateva operatii pentru fiecare cont din tabela Conturi.
Rulati secventele:
15
FROM Deponent AS d, Conturi AS c, Operatii AS o
WHERE d.nr_buletin=c.nr_buletin AND c.nr_cont=o.nr_cont;
# Folosirea tabelei Conturi doar ca tabela de legatura
mysql> SELECT d.nr_buletin, d.nume, o.suma, o.data
FROM Deponent AS d, Conturi AS c, Operatii AS o
WHERE d.nr_buletin=c.nr_buletin AND c.nr_cont=o.nr_cont;
# Folosirea conditiei de selectie impreuna cu cea de join:
# afisarea doar a operatiilor efectuate luna ianuarie
mysql> SELECT d.nr_buletin, d.nume, c.nr_cont, c.tip_cont, o.suma, o.data
FROM Deponent AS d, Conturi AS c, Operatii AS o
WHERE d.nr_buletin=c.nr_buletin AND c.nr_cont=o.nr_cont AND MONTH(data)=1;
Variantele posibile la operatia de JOIN se refera la modul in care sunt tratate inregistrarile care nu au corespondenta in fiecare
tabela legata relational de tabelele in care inregistrarile respective apar.
Principial, rezultatul operatiei de JOIN poate include sau nu inregistrarile fara corespondenta. In primul caz operatia se numeste
OUTER JOIN, iar in cel de al doilea INNER JOIN.
Operatia de OUTER JOIN va completa automat campurile care lipsesc din tabela corespondenta cu valoarea NULL. Un OUTER
JOIN are la randul sau doua varinate. Ambele includ toate inregistrarile care au corespondenta in ambele parti ale relatiei. In plus,
LEFT OUTER JOIN va include in rezultat si inregistrarile din tabela stanga care nu au corespondent in tabela din partea dreapta a
relatiei. In opozitie, RIGHT OUTER JOIN va include in rezultat si inregistrarile din tabela din dreapta care nu au corespondent in
tabela din partea stanga.
Operatia de INNER JOIN nu are variate pe stanga sau pe dreapta, pentru ca in ambele cazuri se vor include in rezultat doar
capurile care au corespondent la ambele capete ale relatiei.
Daca lista de tabele din SELECT cuprinde doar tabele despartite prin virgula se considera implicit o operatie de INNER JOIN.
SELECT lista_campuri
FROM tabela [INNER JOIN | LEFT OUTER JOIN | RIGHT OUTER JOIN] tabela ON conditie_join ...
WHERE conditii_selectie
ORDER BY ...
 ...
In cazul acesta se observa ca specificarea conditiei de join (legatura relationala dintre tabele) se face dupa fiecare pereche de
tabele printr-o clauza ON separata. In mod natural, clauza WHERE va contine aici doar conditiile suplimentare de filtrare a
inregistrarilor dorite.
16
mysql> SELECT d.nr_buletin, d.nume, c.nr_cont
FROM Deponent AS d RIGHT OUTER JOIN Conturi AS c
ON d.nr_buletin=c.nr_buletin;
# Operatia de OUTER JOIN poate fi folosita si pentru a lista toate inregistrarile
# fara corespondenta, de ex. persoanele fara cont la un moment dat
mysql> SELECT d.nr_buletin, d.nume, c.nr_cont
FROM Deponent AS d LEFT OUTER JOIN Conturi AS c
ON d.nr_buletin=c.nr_buletin
WHERE isNULL(c.nr_cont);
Informatiile de sumarizare reprezinta informatii globale despre datele din tabele. Informatiile de sumarizare se extrag pe grupuri
de inregistrari. Mai mult, ele nu au sens decat in contextul gruparii datelor.
SELECT lista_campuri
FROM lista_tabele
WHERE conditii_selectie
GROUP BY {colana | expresie}
HAVING conditie_includere_grup
ORDER BY ...
 ...
Clauza GROUP BY specifica dupa ce valoare se va face gruparea. In majoritatea cazurilor expresia de grupare este reprezentata
de o singura coloana. Toate inregistrarile cu aceeasi valoare pentru expresia de grupare vor fi considerate ca facand parte din
acelasi grup.
Daca clauza GROUP BY lipseste, dar in lista_campuri apar informatii de sumarizare se considera implicit ca toate inregistrarile
fac parte din acelasi grup.
Clauza HAVING permite selectarea grupurilor care sunt luate in considerare. Conditia din HAVING se aplica dupa constituirea
grupului, pe cand conditia din clauza WHERE in timpul selectarii inregistrarilor. In plus, acesta clauza poate cuprinde doar
referinte la campuri si aliasuri de campuri din lista de campuri a comenzii SELECT sau functii de sumarizare pe grup.
Lista de campuri din comanda SELECT poate include urmatoarele functii de sumarizare:
Atentie! Nu este permisa combinarea functiilor de sumarizare cu campurile din tabele decat in cazul in care campurile respective
au o valoare unica in cadrul grupului. In cele mai multe cazuri acestea vor fi campurile din clauza GROUP BY.
17
Rulati secventele:
18