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.
-- 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:
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(zonderALL) verwijdert duplicaten — voert effectief eenDISTINCTover het eindresultaat;UNION ALLbewaart ook duplicaten en is hierdoor veel sneller vermijdt de sortering/hash voor deduplicatie.
-- 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").
-- 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
U kunt een e-mail sturen naar de klant die de OPPURE-recensies heeft ontvangen (duplicati). Een colonna: e-mail. Ordina per e-mail.
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
Trova le e-mail van de klant die geen enkele recensie meer heeft. VS BEHALVE. Een colonna: e-mail. Ordina per e-mail.
Toon hint
EXCEPT bewaart alleen de rijen van de linker SELECT die niet aanwezig zijn in de rechter.
Oplossing beschikbaar na 3 pogingen