SQL COALESCE: sintassi e differenze con ISNULL

tutorial COALESCE su SQL server

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 NUL
  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. Quì 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 alla 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

 

Articoli correlati

Se vuoi approfondire l’utilizzo della funzione SUBSTRING di SQL Server puoi leggere questo mio articolo.

Torna su