Simulare le operazioni sugli insiemi con i join
Riscrivere EXCEPT e INTERSECT nei dialetti che non li supportano
Simulare le operazioni sugli insiemi con i join è una lezione Coding Interview Prep gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Coding Interview Prep, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Coding Interview Prep include 4 lezioni in totale.
Perché simulare le operazioni di insieme
Non tutti i database supportano INTERSECT ed EXCEPT. Le versioni meno recenti di MySQL, per esempio, ne erano completamente prive. Gli intervistatori verificano se sa riprodurre la logica degli insiemi con join e sottoquery quando l'operatore non è disponibile.
Conoscere sia l'operatore di insieme sia l'equivalente con join dimostra che comprende cosa calcola realmente l'operatore.
INTERSECT come INNER JOIN
INTERSECT individua le righe comuni a entrambi gli insiemi. L'equivalente con join è una INNER JOIN su tutte le colonne confrontate, più DISTINCT per riprodurre il comportamento di deduplicazione.
Ogni colonna del confronto diventa parte del predicato della join.
-- A INTERSECT B emulated:
SELECT DISTINCT a.customer_id
FROM orders_2023 a
JOIN orders_2024 b
ON a.customer_id = b.customer_id;Perché DISTINCT è necessario per INTERSECT
Una INNER JOIN semplice può moltiplicare le righe: se un valore compare più volte su uno dei due lati, la join moltiplica le righe. L'INTERSECT standard restituisce ogni riga comune una sola volta, quindi è necessario aggiungere DISTINCT per eliminare i duplicati introdotti dalla join.
Dimenticare DISTINCT in questo caso è un errore frequente nei colloqui.
-- without DISTINCT, a customer with 3 orders in each year
-- would appear 9 times from the joinEXCEPT come LEFT JOIN / IS NULL
EXCEPT (A ma non B) è l'anti-join. La forma portabile consiste nell'applicare un LEFT JOIN da A a B su tutte le colonne, mantenendo solo le righe in cui il lato B è NULL (nessuna corrispondenza), quindi applicando DISTINCT.
Questo schema LEFT JOIN / IS NULL è uno dei trucchi più riutilizzati nei colloqui su SQL.
SELECT DISTINCT a.customer_id
FROM orders_2023 a
LEFT JOIN orders_2024 b
ON a.customer_id = b.customer_id
WHERE b.customer_id IS NULL;EXCEPT con NOT EXISTS
Un modo altrettanto portabile di implementare EXCEPT usa NOT EXISTS. Si legge così: "mantieni ogni riga di A per la quale non esiste alcuna riga corrispondente in B" e gestisce i valori NULL in modo affidabile.
Molti ingegneri preferiscono NOT EXISTS perché il suo intento è esplicito e consente di evitare il problema di NOT IN + NULL.
SELECT DISTINCT a.customer_id
FROM orders_2023 a
WHERE NOT EXISTS (
SELECT 1 FROM orders_2024 b
WHERE b.customer_id = a.customer_id
);INTERSECT con EXISTS
In modo simmetrico, INTERSECT può essere scritto con EXISTS: mantieni ogni riga distinta di A per la quale esiste una riga corrispondente in B.
EXISTS interrompe la ricerca alla prima corrispondenza, quindi può essere efficiente ed evita la moltiplicazione delle righe dovuta al join, eliminando talvolta la necessità di usare DISTINCT sul lato del join.
SELECT DISTINCT a.customer_id
FROM orders_2023 a
WHERE EXISTS (
SELECT 1 FROM orders_2024 b
WHERE b.customer_id = a.customer_id
);La trappola di NULL con NOT IN
Una tentativa allettante di emulare EXCEPT consiste nell'usare NOT IN, ma è pericolosa: se la sottoquery restituisce anche un solo NULL, NOT IN non restituisce alcuna riga perché il confronto diventa UNKNOWN.
È un'insidia verificata molto spesso. Preferisca NOT EXISTS o LEFT JOIN / IS NULL, che gestiscono NULL in modo sicuro.
-- RISKY if orders_2024.customer_id can be NULL:
SELECT DISTINCT customer_id FROM orders_2023
WHERE customer_id NOT IN (
SELECT customer_id FROM orders_2024
);Corrispondenze su più colonne
Quando il confronto tra insiemi coinvolge più colonne, ogni colonna deve comparire nel predicato del join. Per un anti-join è inoltre necessario gestire la possibilità che tali colonne contengano NULL: è proprio qui che NOT EXISTS dà il meglio di sé.
Specifichi ogni colonna nella clausola ON; ometterne una modifica silenziosamente il significato di "riga uguale".
SELECT DISTINCT a.id, a.city
FROM a
LEFT JOIN b
ON a.id = b.id AND a.city = b.city
WHERE b.id IS NULL;Emulare UNION senza l'operatore
UNION ALL è semplicemente una concatenazione, supportata direttamente da ogni dialetto. Per emulare UNION distinta quando necessario, concateni con UNION ALL all'interno di una sottoquery e racchiuda il risultato in un SELECT DISTINCT oppure in un GROUP BY su tutte le colonne.
Questo mostra che UNION è semplicemente UNION ALL più un passaggio di deduplicazione.
SELECT DISTINCT * FROM (
SELECT city FROM a
UNION ALL
SELECT city FROM b
) combined;Scegliere l'emulazione corretta
Guida alla scelta:
- INTERSECT →
EXISTSoppure INNER JOIN + DISTINCT. - EXCEPT →
NOT EXISTSoppure LEFT JOIN / IS NULL. - Eviti
NOT INquando sono possibili valori NULL. - UNION → UNION ALL racchiuso in DISTINCT.
EXISTS / NOT EXISTS sono le soluzioni più portabili e sicure rispetto ai NULL, perciò rappresentano le risposte più affidabili nei colloqui.
Mettere insieme i concetti
Saper tradurre gli operatori sugli insiemi in join dimostra di comprenderli come logica insiemistica, non come semplice sintassi. L'anti-join (LEFT JOIN / IS NULL o NOT EXISTS) è lo schema più importante: compare nell'emulazione di EXCEPT, nella ricerca di record orfani e in tutte le domande sui record mancanti.
Inizi con NOT EXISTS per garantire la correttezza, poi menzioni la forma con join per discutere delle prestazioni.
Verifica rapida
Il database in uso non supporta EXCEPT. Sono necessari i customer_ids presenti in orders_2023 ma non in orders_2024, e la colonna può contenere NULL.
Riepilogo
Punti chiave:
INTERSECT→ INNER JOIN + DISTINCT, oppureEXISTS.EXCEPT→ LEFT JOIN / IS NULL, oppureNOT EXISTS(anti-join).- Aggiunga
DISTINCTper riprodurre il comportamento di deduplicazione degli operatori sugli insiemi e contenere la moltiplicazione delle righe nei join. - Eviti
NOT INquando sono possibili valori NULL; preferisca NOT EXISTS. UNION= UNION ALL racchiuso in DISTINCT.
Domande Frequenti
La lezione «Simulare le operazioni sugli insiemi con i join» è gratuita?
Sì — il testo completo di «Simulare le operazioni sugli insiemi con i join» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Coding Interview Prep, passa a CoddyKit PRO. Il corso Coding Interview Prep include 4 lezioni in totale.
Cosa imparerò in «Simulare le operazioni sugli insiemi con i join»?
Riscrivere EXCEPT e INTERSECT nei dialetti che non li supportano Eserciti Coding Interview Prep con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Coding Interview Prep?
Non è richiesta alcuna esperienza precedente. Coding Interview Prep su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.
Quanto tempo richiede la lezione «Simulare le operazioni sugli insiemi con i join»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Coding Interview Prep?
Sì. Ogni lezione Coding Interview Prep include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- UNION e UNION ALL
- Compatibilità del numero e dei tipi di colonne
- INTERSECT ed EXCEPT per i confronti
- Simulare le operazioni sugli insiemi con i join