SQL COALESCE: sintassi e differenze con ISNULL

COALESCE è un’espressione del linguaggio SQL utilizzata per gestire i NULL all’interno di una query SQL. In questo tutorial vedremo alcuni esempi d’uso della COALESCE basati sul database Microsoft SQL Server e confronteremo i risultati con quelli della funzione ISNULL.

COALESCE su SQL Server

Supponiamo di voler scrivere una query che estrae:

  • la partita Iva dei clienti se è essa è NOT NULL;
  • il codice fiscale se la partita Iva è NULL.

Potremmo scrivere una query SQL che utilizza l’espressione CASE WHEN

SELECT 
 CASE WHEN PartitaIva IS NOT NULL
      THEN PartitaIva
      ELSE CodiceFiscale
 END
FROM Clienti;

COALESCE è semplicemente una “scorciatoia” per riscrivere il codice precedente con la CASE WHEN in maniera più compatta e veloce. Infatti, con COALESCE ci basterà scrivere

SELECT COALESCE(PartitaIva, CodiceFiscale)
FROM   Clienti;

Vediamo il risultato in questa immagine

esempio risultato coalesce SQL

Numero parametri della COALESCE

L’espressione COALESCE può contenere un numero qualsiasi di argomenti. Possiamo scrivere ad esempio

SELECT COALESCE(NULL, NULL, 'Nicola', 'Giovanni');

il risultato sarà Nicola perché è il primo argomento a non essere null. La query precedente infatti è equivalente a

SELECT 
 CASE 
  WHEN NULL IS NOT NULL
   THEN NULL
  WHEN NULL IS NOT NULL
   THEN NULL
  WHEN 'Nicola' IS NOT NULL
   THEN 'Nicola'
  WHEN 'Giovanni' IS NOT NULL
   THEN 'Giovanni'
 END;

che restituisce effettivamente ‘Nicola’ perché è il valore corrispondente al primo ramo WHEN verificato.

Differenze tra COALESCE e ISNULL

Come abbiamo visto nei paragrafi precedenti, COALESCE è un’espressione che ci permette semplicemente di abbreviare del codice che potremmo anche scrivere con una CASE WHEN. ISNULL invece è una funzione di SQL Server che accetta due argomenti e restituisce in output

  • il primo argomento se esso è NOT NULL;
  • il secondo argomento altrimenti.

Per quanto lo scopo di COALESCE e ISNULL è il medesimo, sussistono delle importanti differenze tra i due costrutti. In questo articolo della documentazione ufficiale trovate l’elenco completo https://docs.microsoft.com/it-it/sql/t-sql/language-elements/coalesce-transact-sql?view=sql-server-ver16. Qui voglio porre l’accento sulle due differenze che secondo me sono le più importanti. La prima riguarda il tipo del risultato:

  • il tipo dell’output della funzione ISNULL coincide con il tipo del primo argomento; ad esempio il tipo di
    SELECT ISNULL('ciao',1)

    sarà un varchar(4) perché il primo valore è un varchar(4);

  • il tipo dell’output dell’espressione COALESCE è calcolato, analogamente all’espressione CASE WHEN associata, con il tipo che ha precedenza maggiore tra i tipi dei vari argomenti. Ad esempio tra VARCHAR e INT, l’INT ha precedenza maggiore. Segue dunque che l’espressione analoga a quella del punto precedente con il COALESCE restituirà un errore
    SELECT COALESCE('ciao',1)

A questo link trovi l’ordine di precedenza per tutti i tipi di SQL SERVER https://docs.microsoft.com/it-it/sql/t-sql/data-types/data-type-precedence-transact-sql?view=sql-server-ver16.

Per le stesse ragioni l’output di questa query

DECLARE
@x AS VARCHAR(3) = NULL,
@y AS VARCHAR(10) = 'abcdefg';
SELECT 
 COALESCE(@x, @y) AS [COALESCE], 
 ISNULL(@x, @y) AS [ISNULL];

sarà “abcdefg” per la colonna calcolata con il COALESCE e  “abc” per quella calcolata con ISNULL.

A proposito dei tipi, ritornando all’esempio nel primo paragrafo, nel caso in cui la partita iva non fosse di tipo VARCHAR, dovremmo convertirlo esplicitamente per non ottenere un errore in fase di esecuzione. Scriveremmo dunque

SELECT 
 COALESCE(CAST(PartitaIva AS VARCHAR(50)),
          CodiceFiscale)
FROM   Clienti;

Oppure

SELECT 
  ISNULL(CAST(PartitaIva AS VARCHAR(50)),
         CodiceFiscale)
FROM Clienti;

Utilizzo di subquery all’interno di COALESCE e ISNULL

La seconda differenza riguarda il fatto che se utilizziamo una subquery all’interno di uno dei parametri del COALESCE, quest’ultima potrà essere potenzialmente calcolata più volte. Ciò non succede invece per l’ISNULL. Analizziamo ad esempio il piano d’esecuzione delle due query

SELECT 
 C.IdCliente,
 COALESCE(
   (SELECT MAX(Importo) FROM Fatture),
    0)
FROM Clienti;
SELECT 
 C.IdCliente,
 ISNULL(
    (SELECT MAX(Importo) FROM Fatture),
     0)
FROM Clienti;

Nel primo piano d’esecuzione relativo alla COALESCE notiamo che il calcolo sulla tabella fattura viene effettuato due volte, mentre con l’ISNULL appare una volta sola.

differenze sul piano di esecuzione tra coalesce e isnull

Conclusioni su COALESCE e ISNULL

Per quanto sia COALESCE e sia ISNULL siano utilizzate per gestire i NULL, esistono dei casi particolari in cui il loro utilizzo porta a dei risultati differenti. Risulta dunque molto importante conoscere queste casistiche per non incorrere in errori o comportamenti inaspettati. Se vuoi approfondire queste tematiche, su questo sito sono presenti due video-corsi sul linguaggio SQL di difficoltà crescente: https://www.yimp.it/corso-sql-academy/ e https://www.yimp.it/video-corso-t-sql-avanzato-tuning-query/.

Qui trovi altri articoli del blog sul linguaggio SQL:

Torna in alto
Torna su