Spiegazione dei valori SQL NULL: IS NULL, COALESCE, NULLIF e le trappole da evitare

  1. Home
  2. Blog
  3. Database e SQL

Database e SQL

Spiegazione dei valori NULL SQL: IS NULL, COALESCE, NULLIF e le trappole da evitare

NULL provoca alcuni dei bug più silenziosi in SQL, con query che vengono eseguite senza errori ma perdono righe o distorcono le medie. Scopri come si comporta realmente NULL, con esempi testati e come gestirlo in sicurezza.

9 min di lettura
Spiegazione dei valori SQL NULL: IS NULL, COALESCE, NULLIF e le trappole da evitare

Punti chiave

  • NULL indica un valore mancante o sconosciuto. Non è zero e non è una stringa vuota.
  • Provalo con IS NULL, perché = NULL non corrisponde mai a nulla.
  • La maggior parte dei calcoli con NULL danno NULL e WHERE mantiene solo le righe che sono sicuramente vere.
  • Gli aggregati saltano i NULL, il che può modificare silenziosamente una media.

Una query viene eseguita senza errori e restituisce un numero apparentemente sensato, ma mancano alcune righe e la media è errata. Valori SQL NULL sono molto spesso la causa. NULL non si comporta come un valore normale e ciò attira sia i principianti che gli sviluppatori esperti.

Questa guida mostra esattamente come si comporta NULL. Abbiamo eseguito ogni query in SQLite 3.50 e i risultati mostrati provengono da quell’esecuzione. La maggior parte di questo comportamento è SQL standard e notiamo dove i database differiscono, come l’ordinamento NULL e il trattamento di Oracle delle stringhe vuote.

Cos’è NULL?

NULL è un indicatore che indica che un valore è mancante o sconosciuto. Non è un valore nel senso comune del termine, quindi queste sono tutte cose diverse:

Valore Significato Esempio per una colonna telefonica
NULL Sconosciuto o non fornito Non conosciamo il numero
'' Un valore di testo noto e vuoto Inviato come vuoto
0 Il numero zero Non rilevante per il testo, ma reale per gli importi

La differenza conta soprattutto per gli importi. Un bonus pari a 0 significa che la persona non ha ricevuto nulla. Un bonus NULL significa che nessuno lo sa ancora.

La tabella dei campioni

CREATE TABLE employees (
  id INT, name TEXT, phone TEXT, bonus INT, manager_id INT
);

INSERT INTO employees VALUES
 (1,'Meera','555-0101',500,NULL),
 (2,'Arjun',NULL,300,1),
 (3,'Sara','',NULL,1),
 (4,'Ravi',NULL,NULL,2);

Nota che Sara ha una stringa vuota per il telefono, mentre Arjun e Ravi hanno NULL. I due vengono trattati in modo molto diverso.

Test per NULL

Ecco l’errore che quasi tutti commettono all’inizio:

SELECT name FROM employees WHERE phone = NULL;
-- (no rows)

SELECT name FROM employees WHERE phone IS NULL;
-- Arjun
-- Ravi

SELECT name FROM employees WHERE phone IS NOT NULL;
-- Meera
-- Sara

La prima query è SQL valida e non restituisce errori. Semplicemente non restituisce nulla, perché confrontare qualsiasi cosa con NULL non è mai vero. Sara appare sotto IS NOT NULL, poiché una stringa vuota è un valore reale. In Oracle, tuttavia, una stringa vuota viene trattata come NULL, il che rappresenta un’eccezione notevole.

Logica a tre valori

Nella maggior parte dei linguaggi di programmazione, una condizione è vera o falsa. SQL aggiunge un terzo risultato: sconosciuto. Se non conosci un valore, non puoi dire se è uguale a 5. E non è noto che due valori sconosciuti siano uguali, motivo per cui NULL = NULL non è vero. Nel nostro test, tutti questi hanno restituito NULL:

SELECT NULL = NULL, NULL <> 1, 1 + NULL, 'a' || NULL;

-- NULL | NULL | NULL | NULL

La combinazione delle condizioni segue regole attente. Ecco i risultati della nostra esecuzione, dove 1 è vero e 0 è falso:

Espressione Risultato Perché
VERO E NULLO NULL Dipende dalla parte sconosciuta
FALSO E NULLO Falso Falso qualunque sia l’ignoto
VERO O NULLO Vero Vero qualunque sia l’ignoto
FALSO O NULLO NULL Dipende dalla parte sconosciuta
NON NULLO NULL Il contrario di sconosciuto è sconosciuto

Righe che svaniscono da DOVE

WHERE mantiene una riga solo se la sua condizione è vera. Le righe in cui il risultato è sconosciuto vengono eliminate, insieme a quelle false. Ciò porta a risultati sorprendenti:

SELECT name FROM employees WHERE phone <> '555-0101';

-- Sara

Potresti aspettarti che appaiano Arjun e Ravi, dal momento che il loro telefono certamente non è quel numero. Ma il loro telefono è sconosciuto, quindi il risultato è sconosciuto e svaniscono. Per includerli, ditelo esplicitamente: WHERE phone <> '555-0101' OR phone IS NULL. Anche la negazione non aiuta:

SELECT name FROM employees WHERE NOT (bonus > 400);

-- Arjun

Sara e Ravi non hanno bonus, quindi non compaiono né in bonus > 400 né nel suo opposto. Questa è una cosa fondamentale da ricordare: una condizione e la sua negazione non sempre coprono ogni riga.

COALESCE: fornire un fallback

COALESCE restituisce il primo valore non NULL nel suo elenco e funziona su tutti i principali database:

SELECT COALESCE(NULL, NULL, 'third', 'fourth');
-- third

SELECT name, COALESCE(phone, 'no phone') FROM employees;
-- Meera | 555-0101
-- Arjun | no phone
-- Sara  |
-- Ravi  | no phone

Sara appare ancora vuota, perché una stringa vuota non è NULL. Esistono funzioni simili, come IFNULL in MySQL e SQLite, ISNULL in SQL Server e NVL in Oracle. COALESCE è la scelta portatile. Anche qui vale il nostro punto precedente sui calcoli. bonus + 100 dà NULL per chiunque non abbia un bonus, quindi scrivi COALESCE(bonus, 0) + 100 se trattare un bonus mancante come zero è corretto per la tua attività.

NULLIF: trasforma un valore in NULL

NULLIF(a, b) restituisce NULL se i due valori sono uguali, altrimenti restituisce a. Due usi sono particolarmente utili. Può ripulire i valori segnaposto:

SELECT name, NULLIF(phone, '') FROM employees WHERE id = 3;
-- Sara | NULL

SELECT name FROM employees
WHERE COALESCE(NULLIF(phone, ''), '') = '';
-- Arjun
-- Sara
-- Ravi

La seconda query è un modo pratico per trovare valori “mancanti o vuoti”. Può anche evitare la divisione per zero, che genera un errore in molti database:

SELECT total / NULLIF(quantity, 0) FROM sales;

Quando quantity è 0, ciò fornisce NULL anziché fallire. Nel nostro test, SELECT 100 / NULLIF(0, 0) ha restituito NULL.

Gli aggregati saltano NULL

È qui che NULL causa il maggior danno ai report:

SELECT COUNT(*), COUNT(bonus), SUM(bonus), AVG(bonus),
       AVG(COALESCE(bonus, 0))
FROM employees;

-- 4 | 2 | 800 | 400.0 | 200.0
Espressione Risultato Cosa significa
COUNT(*) 4 Tutte le righe
COUNT(bonus) 2 Solo righe con bonus
SUM(bonus) 800 I NULL vengono ignorati
AVG(bonus) 400 800 diviso per 2, non per 4
AVG(COALESCE(bonus, 0)) 200 800 diviso 4

Allora qual è il bonus medio, 400 o 200? Dipende da cosa significa NULL nei tuoi dati. Se NULL significa “nessun bonus è stato pagato”, allora 200 è corretto. Se significa “non ancora deciso”, allora 400 potrebbe essere giusto. Il database non può prendere questa decisione per te, quindi la domanda deve essere rivolta a qualcuno che conosce l’attività.

Una trappola correlata: SUM senza valori è NULL anziché 0. Quando abbiamo sommato solo le righe senza bonus, abbiamo ottenuto NULL, mentre COUNT ha restituito 0. Il codice dell’applicazione che prevede un numero può bloccarsi su questo, quindi racchiudilo: COALESCE(SUM(bonus), 0).

Suggerimento: Quando il totale del rapporto sembra inadeguato, confronta COUNT(*) con COUNT(column). Qualsiasi spazio tra loro ti dice subito quanti NULL ha quella colonna.

GRUPPO PER, ordinamento e DISTINTO

Sebbene i NULL siano “non uguali” nei confronti, queste operazioni li trattano come un unico gruppo:

SELECT bonus, COUNT(*) FROM employees GROUP BY bonus ORDER BY bonus;
-- NULL | 2
--  300 | 1
--  500 | 1

SELECT DISTINCT bonus FROM employees;
-- 500, 300, NULL

Vedi SQL GROUP BY e HAVING per ulteriori informazioni sul raggruppamento. L’ordinamento è il punto in cui i database differiscono davvero. SQLite e MySQL trattano NULL come il valore più piccolo, mentre PostgreSQL e Oracle lo trattano come il più grande. Quindi lo stesso ORDER BY bonus DESC può mettere i NULL per ultimi in uno e per primi in un altro. PostgreSQL, Oracle e SQLite moderno ti consentono di affermarlo direttamente, utilizzando NULLS FIRST o NULLS LAST.

Si unisce

Una condizione di join che utilizza = non corrisponde mai a NULL, quindi le righe con una chiave NULL escono da un inner join:

SELECT e.name FROM employees e
JOIN employees m ON m.id = e.manager_id;
-- Arjun, Sara, Ravi    (Meera is gone)

SELECT e.name, m.name FROM employees e
LEFT JOIN employees m ON m.id = e.manager_id;
-- Meera | NULL
-- Arjun | Meera
-- Sara  | Meera
-- Ravi  | Arjun

Meera non ha un manager, quindi un inner join elimina silenziosamente quella riga. A LEFT JOIN lo mantiene e crea anche NULL per il lato mancante. Ulteriori informazioni sono disponibili in Spiegazione dei join SQL.

La trappola del NON IN

Un singolo NULL in un elenco NOT IN cancella ogni risultato:

SELECT name FROM employees WHERE manager_id NOT IN (1);
-- Ravi

SELECT name FROM employees WHERE manager_id NOT IN (1, NULL);
-- (no rows)

La seconda forma significa manager_id <> 1 AND manager_id <> NULL e l’ultima parte non potrà mai essere vera. Ciò è particolarmente pericoloso con le subquery, dove un NULL può arrivare inosservato. Utilizza invece NOT EXISTS, come spiegato nel nostro tutorial sulle sottoquery SQL. Anche Meera manca dal primo risultato, poiché manager_id di quella riga è NULL.

Progettare con NULL

  • Utilizzare NOT NULL per impostazione predefinita. Consenti NULL solo quando un valore può veramente mancare.
  • Aggiungi impostazioni predefinite sensate. Ad esempio, quantity INT NOT NULL DEFAULT 0.
  • Non utilizzare valori magici. Una data 01-01-1900 o un’età di -1 al posto di “sconosciuto” corromperanno i tuoi calcoli.
  • Conosci il comportamento UNIQUE. La maggior parte dei database consente diversi NULL in una colonna UNIQUE e il nostro test ne ha inseriti due senza errori. SQL Server rappresenta un’eccezione, poiché normalmente ne consente una.
  • Ricorda che una chiave primaria non può essere NULL. Vedi Chiave primaria e chiave esterna.
  • Test con NULL. I dati di test senza NULL nascondono questi bug. Includili di proposito, come faresti con altri casi limite.

Considerazioni finali

Tratta NULL come “sconosciuto” e la maggior parte del suo comportamento inizia ad avere senso: sconosciuto più uno è sconosciuto e sconosciuto uguale sconosciuto non è noto per essere vero. Controlla uno dei tuoi rapporti questa settimana. Controlla le colonne nullable utilizzando COUNT(*) contro COUNT(column), cerca qualsiasi NOT IN e decidi cosa dovrebbe significare NULL in ciascuna media.

Domande frequenti

Cos’è NULL in SQL?

NULL è un indicatore per un valore mancante o sconosciuto. È diverso da zero e da una stringa vuota e richiede una gestione speciale nei confronti.

Perché = NULL non funziona?

Confrontando qualsiasi cosa con NULL si ottiene un valore sconosciuto anziché vero, quindi WHERE scarta la riga. Utilizzare IS NULL o IS NOT NULL per verificarlo.

Qual è la differenza tra COALESCE e ISNULL?

COALESCE è SQL standard e accetta molti argomenti. ISNULL è specifico di SQL Server e ne richiede due. Per il codice portatile, preferisci COALESCE.

COUNT include valori NULL?

COUNT(*) conta tutte le righe, comprese quelle con NULL. COUNT(colonna) conta solo le righe in cui la colonna non è NULL, il che può fornire un numero più piccolo.

NULL è uguale a una stringa vuota?

No, nella maggior parte dei database. Una stringa vuota è un valore noto senza caratteri e NULL significa sconosciuto. Oracle è un’eccezione notevole, poiché tratta le stringhe vuote come NULL.

Continua a imparare

Lavora con Stack Quora

Hai bisogno di aiuto con test, WordPress o SEO?

Aiutiamo i team a fornire software migliore e a far crescere i loro siti. Raccontaci a cosa stai lavorando e ti suggeriremo chiaramente il prossimo passo.

Continua a leggere

Altre guide su test, intelligenza artificiale e sviluppo moderno

Ti è piaciuto questo articolo? Scegli un argomento e passa direttamente ai nostri tutorial più recenti.

Intelligenza artificiale

Spiegazione delle allucinazioni dell'intelligenza artificiale: perché i modelli linguistici inventano le cose e come ridurle

Spiegazione delle allucinazioni dell'intelligenza artificiale: cosa sono, perché i modelli linguistici le producono, tipi comuni, come ridurle con b…

Leggi l'articolo →
DevOps

Spiegazione delle variabili d'ambiente: file .env, segreti e configurazione eseguiti correttamente

Variabili d'ambiente spiegate con esempi Python che abbiamo eseguito: lettura e impostazione, perché ogni valore è una stringa, file .env, ereditari…

Leggi l'articolo →
Sviluppo software

Spiegazione della limitazione della velocità API: algoritmi, intestazioni e gestione degli errori 429

La limitazione della velocità dell'API spiegata con una simulazione che abbiamo eseguito: bucket di token, finestra fissa, finestra scorrevole, risp…

Leggi l'articolo →
Automazione dei test

Derisione in Python: unittest.mock, patch e gli errori che fanno mentire i test

Mocking in Python con unittest.mock, testato: Mock e return_value, side_effect, patch dove viene utilizzato un nome, specifiche e autospec, date moc…

Leggi l'articolo →
Test del software

Spiegazione della copertura del codice: copertura di linea o di filiale e cosa significa realmente il 100%.

Copertura del codice spiegata con una vera esecuzione di cover.py: copertura di linea, ramo e condizione, lettura di un rapporto, perché la copertur…

Leggi l'articolo →
Database e SQL

DELETE vs TRUNCATE vs DROP in SQL: differenze, rollback e quando utilizzarli

DELETE vs TRUNCATE vs DROP spiegato con SQL testato: cosa rimuove, rollback, trigger, reimpostazione dell'identità, velocità e come differiscono Pos…

Leggi l'articolo →
Database e SQL

Spiegazione delle visualizzazioni SQL: crea, utilizza ed evita le insidie, con esempi

Viste SQL spiegate con le query che abbiamo eseguito: creazione di una vista, risultati in tempo reale, nascondere colonne, prestazioni, viste aggio…

Leggi l'articolo →
Sviluppo software

Interfaccia TypeScript e tipo: differenze reali, testate con il compilatore

Interfaccia TypeScript vs tipo, verificata con il vero compilatore: cosa possono fare entrambi, cosa può fare solo uno, fusione delle dichiarazioni,…

Leggi l'articolo →
Sviluppo software

Spiegazione di Python *args e **kwargs: funzioni flessibili con esempi chiari

Python *args e **kwargs spiegati con il codice che abbiamo eseguito: compressione e decompressione, ordine dei parametri, argomenti solo per parole …

Leggi l'articolo →
Sviluppo software

Funzioni Lambda Python: sintassi, usi reali e quando non usarli

Funzioni lambda Python spiegate con il codice che abbiamo eseguito: sintassi, ordinamento con chiave, mappa e filtro, chiusure, trap dell'associazio…

Leggi l'articolo →
Intelligenza artificiale

Cosa sono gli agenti AI? Come funzionano, con un semplice ciclo di agenti che puoi eseguire

Cosa sono gli agenti IA? Una semplice guida al ciclo dell'agente, agli strumenti, alla memoria e ai guardrail, con un piccolo ciclo Python che abbia…

Leggi l'articolo →
DevOps

Monitoraggio vs osservabilità: la vera differenza, con log, metriche e tracce

Spiegazione del monitoraggio e dell'osservabilità: errori noti e sconosciuti, log, metriche e tracce, una procedura dettagliata sugli incidenti di p…

Leggi l'articolo →
DevOps

Volumi Docker e montaggi di associazione: mantenere i dati del contenitore nel modo giusto

Volumi Docker e montaggi di collegamento spiegati: perché i dati del contenitore scompaiono, volumi denominati, montaggi di collegamento, tmpfs, ese…

Leggi l'articolo →
Automazione dei test

TDD vs BDD: differenze chiave, una caratteristica costruita in entrambi i modi e quando utilizzarli ciascuno

TDD vs BDD spiegato con una funzione di sconto costruita in entrambi i modi: refactoring rosso-verde con il codice che abbiamo eseguito, scenari "Da…

Leggi l'articolo →
Test del software

Test di accettazione da parte dell'utente (UAT): processo, lista di controllo ed esempi reali

Spiegazione del test di accettazione dell'utente: chi lo esegue, in cosa differisce dal QA, un processo in sette fasi, un modello di test case UAT, …

Leggi l'articolo →
Database e SQL

Spiegazione dei valori SQL NULL: IS NULL, COALESCE, NULLIF e le trappole da evitare

Valori SQL NULL spiegati con le query che abbiamo eseguito: logica a tre valori, IS NULL, COALESCE, NULLIF, come aggregazioni, join e ordinamento tr…

Leggi l'articolo →
Database e SQL

Istruzione SQL CASE WHEN: sintassi, esempi reali ed errori comuni

SQL CASE WHEN spiegato con le query che abbiamo eseguito: moduli semplici e cercati, ordine delle condizioni, pivot con SUM, trucchi COUNT, ordiname…

Leggi l'articolo →
Sviluppo software

Cos'è il JWT? Token Web JSON spiegati con un esempio funzionante

Cos'è il JWT? Spiegazione dei token Web JSON: le tre parti, un token creato e manomesso nel codice che abbiamo eseguito, JWT e sessioni, archiviazio…

Leggi l'articolo →
Sviluppo software

Spiegazione del loop di eventi JavaScript: stack di chiamate, microtask e timer con esempi

Il ciclo di eventi JavaScript spiegato con il codice che abbiamo eseguito: stack di chiamate, code di attività e microtask, perché setTimeout 0 non …

Leggi l'articolo →
Sviluppo software

Spiegazione dei generatori Python e del rendimento: risparmia memoria con esempi reali

Generatori Python e rendimento spiegati con il codice che abbiamo eseguito: come vengono messi in pausa e ripresi, misurato il risparmio di memoria,…

Leggi l'articolo →
Intelligenza artificiale

Cosa sono gli incorporamenti? I vettori e la somiglianza del coseno spiegati semplicemente

Cosa sono gli incorporamenti? Una guida in linguaggio semplice ai vettori, alla similarità del coseno e alla ricerca semantica, con un piccolo esemp…

Leggi l'articolo →
DevOps

Distribuzione blu-verde rispetto a quella canaria: differenze, compromessi e come scegliere

Spiegazione della distribuzione blu-verde e canary: come funziona ciascuna, costi, rischi e rollback, bucket utente stabile che abbiamo testato, mig…

Leggi l'articolo →
Automazione dei test

Test instabili: quali sono le cause e come risolverli definitivamente

Test instabili spiegati con demo che abbiamo eseguito: le cause principali, come confermarne e diagnosticarne uno, soluzioni adeguate per tempistich…

Leggi l'articolo →
Test del software

Test di carico e test di stress: differenze, metriche ed esempi k6

Spiegazione del test di carico e dello stress test: cosa dimostra ciascuno, test di picco e di assorbimento, le metriche che contano, perché le medi…

Leggi l'articolo →
Test del software

Caso di test e scenario di test: differenze chiave, esempi e quando utilizzarli

Spiegazione del caso di test e dello scenario di test: definizioni chiare, una tabella affiancata, una funzione di reimpostazione della password pre…

Leggi l'articolo →
Database e SQL

Ottimizzazione delle query SQL: leggi i piani di esecuzione e correggi query lente, con tempistiche

Ottimizzazione delle query SQL testata su un milione di righe: leggi i piani di esecuzione, aggiungi gli indici corretti, correggi filtri non aggior…

Leggi l'articolo →
Database e SQL

SQL UNION vs UNION ALL: differenze, esempi e prestazioni testate

SQL UNION vs UNION ALL spiegati con le query che abbiamo eseguito: duplicati, regole seguite da entrambi, un vero bug di dati, prestazioni misurate,…

Leggi l'articolo →
Sviluppo software

Tutorial sull'API di recupero JavaScript: GET, POST, gestione degli errori e timeout

Un tutorial sull'API JavaScript Fetch testato su un server locale: GET e POST, perché 404 non genera eccezioni, un helper riutilizzabile, stringhe d…

Leggi l'articolo →
Sviluppo software

Gestione dei file Python: lettura, scrittura, CSV, JSON e pathlib con esempi

Gestione dei file Python spiegata con il codice che abbiamo eseguito: modalità aperte, con, lettura di file di grandi dimensioni, CSV, JSON, pathlib…

Leggi l'articolo →
Sviluppo software

Classi e oggetti Python: tutorial OOP con esempi reali

Classi e oggetti Python spiegati con il codice che abbiamo eseguito: __init__, metodi, attributi di classe e istanza, ereditarietà, proprietà, metod…

Leggi l'articolo →
Intelligenza artificiale

Che cos'è un modello linguistico di grandi dimensioni? Come funzionano i LLM, spiegato senza esagerazioni

Cos’è un modello linguistico ampio? LLM spiegati in un linguaggio semplice: token, incorporamenti, attenzione, formazione, finestre di temperatura e…

Leggi l'articolo →
DevOps

Comandi Linux per principianti: la guida essenziale del terminale con esempi

Comandi Linux per principianti, raggruppati per attività: navigazione, file, visualizzazione log, grep, pipe, permessi, processi e archivi, con un e…

Leggi l'articolo →
Automazione dei test

Selenio vs drammaturgo: differenze chiave, codice a confronto e quale scegliere

Selenium vs Playwright a confronto: architettura, attesa, supporto per browser e linguaggio, debug, lo stesso test in entrambi gli strumenti, consig…

Leggi l'articolo →
Test del software

Partizionamento di equivalenza: tecnica di progettazione dei test spiegata con esempi pratici

Spiegazione del partizionamento di equivalenza: come trovare partizioni valide e non valide, esempi funzionanti per età, password e coupon, test che…

Leggi l'articolo →
Test del software

Gravità vs priorità nel test del software: differenze, matrice ed esempi reali

Spiegazione della gravità e della priorità nei test del software: definizioni chiare, una matrice a quattro vie con esempi, scale di livello, chi im…

Leggi l'articolo →
Database e SQL

Esercitazione sulle sottoquery SQL: tipi, sottoquery correlate ed EXISTS con esempi

Un tutorial sulle sottoquery SQL con le query che abbiamo eseguito: sottoquery scalari, IN, FROM e SELECT, sottoquery correlate, EXISTS, trap NOT IN…

Leggi l'articolo →
Database e SQL

Spiegazione di transazioni SQL e ACID: COMMIT, ROLLBACK e livelli di isolamento

Transazioni SQL e ACID spiegate con un bonifico bancario eseguito: COMMIT, ROLLBACK, punti di salvataggio, blocchi, livelli di isolamento, letture s…

Leggi l'articolo →
Sviluppo software

Git merge vs rebase: differenze, esempi e quando usare ciascuno

Git merge vs rebase spiegato con output reale del log, una tabella di confronto, la regola d'oro del rebase e un flusso di lavoro sicuro per i team.

Leggi l'articolo →
Sviluppo software

List comprehension in Python: sintassi, esempi e quando evitarla

List comprehension in Python spiegata: sintassi, filtri, if-else, cicli annidati, tempi misurati e i casi in cui un normale ciclo for è meglio.

Leggi l'articolo →
Database e SQL

SQL JOIN spiegati con esempi (Inner, Left, Right, Full)

Capisci i JOIN SQL passo dopo passo con tabelle e query di esempio: INNER, LEFT, RIGHT, FULL, CROSS e SELF, con errori comuni e consigli sulle prest…

Leggi l'articolo →