Sunteți pe pagina 1din 13

Curs JOIN si UNION

În SQL, JOIN-urile sunt utilizate pentru a combina înregistrări din două sau mai multe tabele,
bazându-se pe o condiție comună.

Ele permit extragerea de date din mai multe tabele într-o singură interogare și sunt esențiale în
gestionarea bazelor de date relaționale.

MySQL 8 suportă diferite tipuri de JOIN-uri, cum ar fi INNER JOIN, LEFT JOIN, RIGHT JOIN
și FULL JOIN.

O situatie aparte este SELF JOIN

https://dev.mysql.com/doc/refman/8.0/en/join.html

1
1. SELF JOIN este un join obisnuit in care tabela se uneste cu ea insasi

Self join în MySQL 8 este utilizat atunci când dorim să combinăm înregistrări din aceeași tabelă, creând o
relație între înregistrările din aceeași entitate. Self join poate fi util atunci când avem o structură
ierarhică sau relații între înregistrări în cadrul aceleiași tabele.

SELECT e.first_name AS employee_name, m.first_name AS manager_name

FROM employees e

JOIN employees m ON e.emp_no = m.emp_no

WHERE e.emp_no IN (SELECT emp_no FROM dept_manager);

 În acest exemplu, tabela "employees" este folosită de două ori într-un self join.
 Prima mențiune a tabelei "employees" este denumită "e" și reprezintă angajații.
 A doua mențiune a tabelei "employees" este denumită "m" și reprezintă managerii.
 Prin utilizarea clauzei JOIN și a expresiei "e.emp_no = m.emp_no", stabilim relația între
angajați și manageri în baza de date.
 În clauza WHERE, verificăm că numărul de angajat al angajatului există în tabela
"dept_manager", asigurându-ne că angajatul are un manager asociat.
 Rezultatul final va conține o listă de angajați împreună cu numele managerilor lor.

Alt exemplu:

SELECT e.first_name AS employee_name, m.first_name AS manager_name

FROM employees e

JOIN dept_manager dm ON e.emp_no = dm.emp_no

JOIN employees m ON dm.emp_no = m.emp_no;

2. INNER JOIN: INNER JOIN returnează numai înregistrările care au corespondență în


ambele tabele. Este utilizat atunci când doriți să obțineți înregistrările care au valori
comune în coloanele cheie ale ambelor tabele.

2
Exemplu de cod pentru a obține numele angajaților și numele departamentelor în care lucrează:

SELECT employees.first_name, employees.last_name, departments.dept_name


FROM employees
INNER JOIN dept_emp ON employees.emp_no = dept_emp.emp_no
INNER JOIN departments ON dept_emp.dept_no = departments.dept_no;

Sau

SELECT e.first_name, e.last_name, s.salary, d.dept_name


FROM employees e
INNER JOIN salaries s ON e.emp_no = s.emp_no
INNER JOIN dept_emp de ON e.emp_no = de.emp_no
INNER JOIN departments d ON de.dept_no = d.dept_no;

3. Left Join (sau Left Outer Join): Returnează toate înregistrările din tabela din stânga
(prima specificată în clauza JOIN), împreună cu înregistrările corespunzătoare din tabela
din dreapta (a doua specificată), dacă există o potrivire.

Dacă nu există o potrivire, se vor afișa NULL în coloanele din tabela din dreapta.

Se folosește atunci când dorim să obținem toate înregistrările din tabela din stânga și doar
înregistrările corespunzătoare din tabela din dreapta.

Exemplu de cod pentru a obține numele și salariul angajaților, inclusiv cei care nu au salarii:

3
SELECT e.first_name, e.last_name, s.salary
FROM employees e
LEFT JOIN salaries s ON e.emp_no = s.emp_no;

Exemplu de cod pentru a obține numele angajaților și numele departamentelor în care lucrează,
inclusiv angajații care nu sunt atribuiți unui departament:

SELECT employees.first_name, employees.last_name, departments.dept_name


FROM employees
LEFT JOIN dept_emp ON employees.emp_no = dept_emp.emp_no
LEFT JOIN departments ON dept_emp.dept_no = departments.dept_no;

4. Right Join (sau Right Outer Join): Returnează toate înregistrările din tabela din dreapta (a
doua specificată în clauza JOIN), împreună cu înregistrările corespunzătoare din tabela
din stânga (prima specificată), dacă există o potrivire.

Dacă nu există o potrivire, se vor afișa NULL în coloanele din tabela din stânga.

Se folosește mai puțin frecvent decât Left Join, dar este util atunci când dorim să obținem
toate înregistrările din tabela din dreapta și doar înregistrările corespunzătoare din tabela din
stânga.

Exemplu de cod pentru a obține numele departamentelor și numele angajaților care lucrează în
fiecare departament, inclusiv departamentele fără angajați:

SELECT employees.first_name, employees.last_name, departments.dept_name


FROM employees
RIGHT JOIN dept_emp ON employees.emp_no = dept_emp.emp_no
RIGHT JOIN departments ON dept_emp.dept_no = departments.dept_no;

5. Full Join (sau Full Outer Join): Returnează toate înregistrările din ambele tabele,
împreună cu înregistrările care nu au corespondențe în cealaltă tabelă.

Dacă nu există o potrivire, se vor afișa NULL în coloanele corespunzătoare.

4
Se folosește atunci când dorim să obținem toate înregistrările din ambele tabele, inclusiv
înregistrările care nu au corespondențe.

Exemplu de cod pentru a obține numele angajaților și numele departamentelor în care lucrează,
afișând toate înregistrările din ambele tabele:

SELECT employees.first_name, employees.last_name, departments.dept_name


FROM employees
FULL JOIN dept_emp ON employees.emp_no = dept_emp.emp_no
FULL JOIN departments ON dept_emp.dept_no = departments.dept_no;

6. Cross Join (sau Cartesian Join): Returnează toate combinațiile posibile dintre
înregistrările din ambele tabele, rezultând un produs cartezian al acestora. Nu necesită o
condiție de potrivire și poate genera un număr mare de înregistrări. Se folosește rar și în
situații specifice.

Exemplu in care obținem toate combinațiile posibile dintre angajați și departamente:

SELECT e.first_name, e.last_name, d.dept_name


FROM employees e
CROSS JOIN departments d;

Această interogare va returna o listă a tuturor angajaților împreună cu fiecare departament


existent în baza de date, combinând fiecare înregistrare din tabela "employees" cu fiecare

5
înregistrare din tabela "departments". Este important de menționat că această interogare poate
genera un număr mare de înregistrări, în funcție de câte angajați și departamente există în
baza de date.

Exemplul de cod pentru fiecare tip de join utilizând baza de date "employees" este:

 Inner Join:

SELECT e.first_name, e.last_name, s.salary, d.dept_name


FROM employees e
INNER JOIN salaries s ON e.emp_no = s.emp_no
INNER JOIN dept_emp de ON e.emp_no = de.emp_no
INNER JOIN departments d ON de.dept_no = d.dept_no;

 Left Join:

SELECT e.first_name, e.last_name, s.salary


FROM employees e
LEFT JOIN salaries s ON e.emp_no = s.emp_no;

 Right Join:

SELECT e.first_name, e.last_name, s.salary


FROM employees e
RIGHT JOIN salaries s ON e.emp_no = s.emp_no;

 Full Join:

SELECT e.first_name, e.last_name, s.salary


FROM employees e
FULL JOIN salaries s ON e.emp_no = s.emp_no;

 Cross Join:

SELECT e.first_name, e.last_name, d.dept_name


FROM employees e
CROSS JOIN departments d;

6
JOIN, where si order by

SELECT e.emp_no, e.first_name, d.dept_name

FROM employees e

JOIN dept_emp de ON e.emp_no = de.emp_no

JOIN departments d ON de.dept_no = d.dept_no

WHERE e.gender = 'F'

ORDER BY e.first_name ASC;

În acest exemplu, clauza WHERE este adăugată după clauza JOIN pentru a aplica un filtru
suplimentar. Astfel, rezultatul final va conține doar angajate de gen feminin (unde condiția
e.gender = 'F' este îndeplinită). Apoi, clauza ORDER BY este utilizată pentru a sorta rezultatele în
ordine crescătoare a câmpului "first_name" al tabelului "employees".

UNION

UNION în MySQL 8 este un operator care este utilizat pentru a combina rezultatele a două sau
mai multe interogări, rezultând un set de rezultate distincte.

Este important de menționat că UNION operează pe nivelul rezultatelor, în timp ce join-urile


operează pe nivelul tabelelor.

Acesta combină rezultatele orizontale, adică adaugă rândurile rezultatelor unei interogări la
sfârșitul rândurilor rezultatelor celeilalte interogări.

https://dev.mysql.com/doc/refman/8.0/en/union.html

Utilizarea UNION: UNION este folosit atunci când dorim să combinăm rezultatele mai multor
interogări care au aceeași structură de coloane. Adică, rezultatele trebuie să aibă același număr
de coloane și tipurile de date ale acestor coloane trebuie să fie compatibile.

7
O caracteristică importantă a UNION este că elimină automat înregistrările duplicate din setul
de rezultate final. Dacă interogările individuale returnează înregistrări care se suprapun,
rezultatul final va conține doar o singură apariție a acestor înregistrări. Dacă dorim să păstrăm
înregistrările duplicate, putem folosi operatorul UNION ALL în loc de UNION.

Sintaxa generală a UNION este următoarea:

SELECT column1, column2, ...


FROM table1
UNION
SELECT column1, column2, ...
FROM table2;

SELECT emp_no, first_name, last_name


FROM employees
UNION
SELECT emp_no, first_name, last_name
FROM employees;

SELECT first_name FROM employees


UNION
SELECT dept_name FROM departments;

Diferența dintre UNION și join-uri: Principalul punct de diferență dintre UNION și join-uri este că
UNION combină rezultatele interogărilor într-un set distinct de rezultate, în timp ce join-uri
combină înregistrări din tabele diferite, pe baza unei condiții, pentru a obține înregistrări

8
rezultante mai complexe. UNION este utilizat pentru a combina rezultatele, în timp ce join-urile
sunt utilizate pentru a combina înregistrările.

De asemenea, este important să menționăm că UNION nu este limitat la numărul de coloane


comune, pe când join-urile necesită o condiție de potrivire specificată.

În concluzie, UNION este utilizat pentru a combina rezultatele interogărilor distincte într-un set
de rezultate distincte, eliminând duplicatelor. Este important să înțelegem diferența între
UNION și join-uri, deoarece acestea sunt două concepte diferite utilizate în contexte diferite
pentru a obține rezultate specifice.

UNION si exemple de alias pe coloanal

Folosim baza de date employees

SELECT emp_no, first_name, 'Employee'

FROM employees

WHERE emp_no < 1000

UNION

SELECT dm.emp_no, CONCAT(e.first_name, ' ', e.last_name), 'Manager'

9
FROM dept_manager dm

JOIN employees e ON dm.emp_no = e.emp_no;

Sau fara join:

SELECT emp_no, first_name, 'Employee'

FROM employees

WHERE emp_no < 1000

UNION

SELECT emp_no, CONCAT(first_name, ' ', last_name), 'Manager'

FROM employees

WHERE emp_no IN (SELECT emp_no FROM dept_manager);

În acest exemplu, am eliminat aliasurile pentru coloanele "name" și "role" și am folosit direct
numele coloanelor "first_name" și "role" în interogare. Restul codului și funcționalitatea rămân
aceleași ca în exemplul anterior.

Rezultatul final va conține o listă combinată a angajaților și managerilor din baza de date
"employees", cu coloanele "emp_no" pentru numărul angajatului, "first_name" pentru nume și
o coloană suplimentară pentru a indica rolul fiecărei persoane.

10
Folosim union si alias explicit pentru coloana

SELECT emp_no, first_name AS name, 'Employee' AS role

FROM employees

WHERE emp_no < 1000

UNION

SELECT dm.emp_no, CONCAT(e.first_name, ' ', e.last_name) AS name, 'Manager' AS


role

FROM dept_manager dm

JOIN employees e ON dm.emp_no = e.emp_no;

Prima interogare rămâne neschimbată și selectează angajații cu numere de angajat mai mici de
1000.

A doua interogare este modificată pentru a utiliza tabela "dept_manager" pentru a obține
numărul de angajat și a se alătura tabela "employees" pentru a obține numele complet al
managerilor.

Prin utilizarea clauzei JOIN și a expresiei "dm.emp_no = e.emp_no", se asigură că numărul de


angajat din tabela "dept_manager" se potrivește cu numărul de angajat din tabela
"employees".

Rezultatul final va conține o listă combinată a angajaților și managerilor din baza de date
"employees", cu coloanele "emp_no" pentru numărul angajatului, "name" pentru nume și
"role" pentru a indica rolul fiecărei persoane.

11
MySQL UNION și ORDER BY

Dacă doriți să sortați setul de rezultate al unei uniuni, utilizați o ORDER BY clauză în
ultimul  SELECT

SELECT emp_no, first_name, 'Employee'

FROM employees

WHERE emp_no < 1000

UNION

SELECT emp_no, CONCAT(first_name, ' ', last_name), 'Manager'

FROM employees

WHERE emp_no IN (SELECT emp_no FROM dept_manager) order by emp_no;

Se poate folosi ordinea coloanei pentru sortare cu order by:

SELECT emp_no, first_name, 'Employee'

FROM employees

WHERE emp_no < 1000

UNION

SELECT emp_no, CONCAT(first_name, ' ', last_name), 'Manager'

FROM employees

WHERE emp_no IN (SELECT emp_no FROM dept_manager) order by 2;

12
13

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