Salt la conținutul principal
Modulul 5 · Lecția 4 din 420/57 în curs~12 min
Lecții din modul (4/4)

UNIRE, INTERSECT, EXCEPTĂ (și CROSS JOIN)

Până acum ați combinat datele orizontal: JOIN atașează coloane din rândurile aferente. SQL oferă, de asemenea, o altă familie de operatori care combină datele vertical, tratând rezultatele a două SELECTs ca seturi: UNION, INTERSECT, EXCEPT. Revizuim, de asemenea, CROSS JOIN, the produs cartezian.

CROS JOIN: fiecare rând cu fiecare rând

CROSS JOIN nu are ON: produce orice combinație posibilă de rânduri între două tabele (produs cartezian). Dacă A are n rânduri și B are m rânduri, rezultatul are n × m.

SQL
-- Tutte le combinazioni cliente × prodotto:
SELECT c.email, p.name
FROM   customers c
CROSS JOIN products p;

12 clienți × 16 produse = 192 de rânduri. Este rar folosit pe date reale (este scump!), dar este util pentru:

  • generarea de combinații „toate împotriva tuturor” (de exemplu, o matrice de compatibilitate);
  • împerecherea unui tabel cu un mic tabel de constante/parametri.

UNIRE și UNIRE TOȚI

UNION adaugă rezultatele a două SELECTs cu același număr și tip de coloane:

SQL
SELECT email FROM customers WHERE country = 'Italia'
UNION
SELECT email FROM customers WHERE country = 'Francia';

Reguli:

  • cele două SELECT-uri trebuie să aibă același număr de coloane, cu compatibile tipuri;
  • UNION (fără ALL) elimină duplicatele — efectuând eficient o DISTINCT privind rezultatul final;
  • UNION ALL păstrează și duplicatele și este mult mai rapid deoarece evită sortarea/hash-ul pentru deduplicare.
SQL
-- Email di clienti che hanno ordinato O recensito qualcosa, senza duplicati:
SELECT c.email
FROM   customers c JOIN orders  o ON o.customer_id = c.id
UNION
SELECT c.email
FROM   customers c JOIN reviews r ON r.customer_id = c.id;

INTERSECT și EXCEPTĂ

INTERSECT păstrează doar rândurile prezente în ambele rezultate; EXCEPT păstrează rândurile primului care nu sunt în al doilea (setul „diferență”).

SQL
-- Clienti che hanno sia ordinato sia recensito:
SELECT c.email FROM customers c JOIN orders  o ON o.customer_id = c.id
INTERSECT
SELECT c.email FROM customers c JOIN reviews r ON r.customer_id = c.id;

-- Clienti che hanno ordinato ma mai recensito:
SELECT c.email FROM customers c JOIN orders  o ON o.customer_id = c.id
EXCEPT
SELECT c.email FROM customers c JOIN reviews r ON r.customer_id = c.id;

INTERSECT și EXCEPT elimină și duplicatele în mod implicit; cel Variantele INTERSECT ALL / EXCEPT ALL nu.

Încercați-l singur

Exercițiu#sql.m5.l4.e1
Încercări: 0Se încarcă…

Trova tutte le email dei clienti che hanno ordinato qualcosa OPPURE recensito qualcosa (senza duplicati). Una colonna: e-mail. Ordina pe e-mail.

Se încarcă editorul...
Afișează indiciu

UNION între două SELECT-uri care returnează aceeași coloană de e-mail. ORDER BY merge la final, pe rezultatul final.

Soluție disponibilă după 3 încercări

Exercițiu de revizuire

Exercițiu#sql.m5.l4.e2
Încercări: 0Se încarcă…

Trova le email dei clienti che hanno ordinato ma non hanno mai recensito nulla. SUA CU EXCEPȚIA. Una colonna: e-mail. Ordina pe e-mail.

Se încarcă editorul...
Afișează indiciu

EXCEPT păstrează doar rândurile din stânga SELECT care nu sunt prezente în cel din dreapta.

Soluție disponibilă după 3 încercări