Direct naar de hoofdinhoud
Module 5 · Les 4 van 420/57 in de cursus~12 min
Modulelessen (4/4)

UNION, INTERSECT, BEHALVE (en CROSS JOIN)

Tot nu toe heeft u gegevens horizontaal gecombineerd: JOIN voegt kolommen toe uit gerelateerde rijen. SQL biedt ook nog een andere familie van operators combineert gegevens verticaal en behandelt de resultaten van twee SELECTs als sets: UNION, INTERSECT, EXCEPT. We bezoeken ook CROSS JOIN, de cartesiaans product.

CROSS JOIN: elke rij met elke rij

CROSS JOIN heeft geen ON: het produceert elke mogelijke combinatie van rijen tussen twee tabellen (cartesiaans product). Als A n rijen heeft en B heeft m rijen, het resultaat heeft n × m.

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

12 klanten × 16 producten = 192 rijen. Het wordt zelden gebruikt op echte gegevens (het is duur!), maar het is handig voor:

  • het genereren van "alles tegen allen"-combinaties (bijvoorbeeld een compatibiliteitsmatrix);
  • een tabel koppelen aan een kleine tabel met constanten / parameters.

UNIE en UNIE ALLEN

UNION voegt de resultaten toe van twee SELECTs met hetzelfde getal en type kolommen:

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

Regels:

  • de twee SELECTs moeten hetzelfde aantal kolommen hebben, met compatibiliteit soorten;
  • UNION (zonder ALL) verwijdert duplicaten — voert effectief een DISTINCT over het eindresultaat;
  • UNION ALL bewaart ook duplicaten en is hierdoor veel sneller vermijdt de sortering/hash voor deduplicatie.
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;

SNIJDEN en BEHALVE

INTERSECT behoudt alleen de rijen die aanwezig zijn in beide resultaten; EXCEPT behoudt de rijen van de eerste die niet in de tweede staan (de set "verschil").

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 en EXCEPT verwijderen standaard ook duplicaten; de INTERSECT ALL / EXCEPT ALL varianten niet.

Probeer het zelf

Oefening#sql.m5.l4.e1
Pogingen: 0Laden…

U kunt een e-mail sturen naar de klant die de OPPURE-recensies heeft ontvangen (duplicati). Een colonna: e-mail. Ordina per e-mail.

Editor laden…
Toon hint

UNION tussen twee SELECT's retourneert dezelfde e-mailkolom. De ORDER BY gaat aan het einde, op het eindresultaat.

Oplossing beschikbaar na 3 pogingen

Oefening beoordelen

Oefening#sql.m5.l4.e2
Pogingen: 0Laden…

Trova le e-mail van de klant die geen enkele recensie meer heeft. VS BEHALVE. Een colonna: e-mail. Ordina per e-mail.

Editor laden…
Toon hint

EXCEPT bewaart alleen de rijen van de linker SELECT die niet aanwezig zijn in de rechter.

Oplossing beschikbaar na 3 pogingen