it-swarm.it

Usando ISNULL vs usando COALESCE per verificare una condizione specifica?

So che è possibile passare più parametri a COALESCE, ma quando si desidera controllare solo un'espressione per vedere se non esiste, si utilizza un valore predefinito o è consigliabile utilizzare ISNULL invece?

C'è qualche miglioramento delle prestazioni tra i due?

69
JBone

Questo problema segnalato su Microsoft Connect rivela alcune differenze tra COALESCE e ISNULL:

una prima parte della nostra elaborazione riscrive COALESCE( expression1, expression2 ) come CASE WHEN expression1 IS NOT NULL THEN expression1 ELSE expression2 END. In [questo esempio]:

COALESCE ( ( SELECT Nullable
             FROM Demo
             WHERE SomeCol = 1 ), 1 )

generiamo:

SELECT CASE
          WHEN (SELECT Nullable FROM Demo WHERE SomeCol = 1) IS NOT NULL
          THEN (SELECT Nullable FROM Demo WHERE SomeCol = 1)
          ELSE 1
       END

Le fasi successive dell'elaborazione della query non comprendono che le due subquery erano originariamente la stessa espressione, quindi eseguono la subquery due volte ...

Una soluzione alternativa, anche se odio suggerirlo, è di modificare COALESCE in ISNULL, poiché quest'ultimo non duplica la sottoquery.

55
onedaywhen

Penso di no, ma COALESCE è nello standard SQL '92 e supportato da più database diversi. Se preferisci la portabilità, non utilizzare ISNULL.

24
GolezTrol

In COALESCE puoi avere più espressioni, dove come in ISNULL puoi controllare solo una espressione

COALESCE ( expression [ ,...n ] ) 

ISNULL ( check_expression , replacement_value )
11
otti

Vale la pena ricordare che anche la gestione dei tipi tra i due può fare la differenza (vedi questo elemento di risposta correlato (2) ).

Supponiamo che una query tenti di utilizzare un collegamento per scrivere un confronto null:

select * from SomeTable
 where IsNull(SomeNullableBitField, -1) != IsNull(SomeOtherNullableBitField, -1);

che è diverso da

select * from SomeTable
 where coalesce(SomeNullableBitField, -1) != coalesce(SomeOtherNullableBitField, -1);

Perché nel primo caso, IsNull () forza il tipo in modo che sia un po '(quindi -1 viene convertito in vero) mentre il secondo caso promuoverà entrambi in un int.

with input as 
(
  select convert(bit, 1) as BitOn,      
         convert(bit, 0) as BitOff,
         convert(bit, null) as BitNull
)
select BitOn, 
       BitOff,
       BitNull,
       IsNull(BitOn, -1) IsNullBitOn,         -- true
       IsNull(BitOff, -1) IsNullBitOff,       -- false
       IsNull(BitNull, -1) IsNullBitNull,     -- true, converts the -1 to bit
       coalesce(BitOn, -1) CoalesceBitOn,     -- 1
       coalesce(BitOff, -1) CoalesceBitOff,   -- 0       
       coalesce(BitNull, -1) CoalesceBitNull  -- -1
  from input;

C'è un commento/collegamento simile (@Martin Smith) sulla domanda stessa.

7
crokusek

Una cosa importante che non vedo esplicitamente indicato è che il tipo di output di ISNULL è simile alla prima espressione ma con COALESCE restituisce il tipo di dati del valore con la precedenza più alta.

DECLARE @X VARCHAR(3) = NULL
DECLARE @Y VARCHAR(10) = '123456789'
/* The datatype returned is similar to X, or the first expression*/
SELECT ISNULL(@X, @Y) ---> Output is '123'
/* The datatype returned is similar to Y, or to the value of highest precedence*/
SELECT COALESCE(@X, @Y) ---> Output is '123456789'
5
BICube

Questa spiegazione fornisce chiarimenti sulla coesione vs isnull

La funzione COALESCE in SQL restituisce la prima espressione non NULL tra i suoi argomenti. La sintassi di COALESCE è la seguente:

 COALESCE ("expression 1", "expressions 2", ...)

È lo stesso della seguente istruzione CASE:

SELECT CASE ("column_name")
  WHEN "expression 1 is not NULL" THEN "expression 1"
  WHEN "expression 2 is not NULL" THEN "expression 2"
  ...
  [ELSE "NULL"]
  END
FROM "table_name";

In SQL Server, la funzione ISNULL () viene utilizzata per sostituire il valore NULL con un altro valore.

select CountryName = ISNULL("columnname", 'INDIA') from Countries

Coalesce restituisce la prima espressione non nulla in cui asnull () viene utilizzato per sostituire il valore null con il valore desiderato.

COALESCE fa parte degli standard ANSI e sono disponibili in quasi tutti i database.

quando si decide tra ISNULL v COALESCE, occorre prestare attenzione ai parametri:

  1. COALESCE determina il tipo di output in base alla precedenza del tipo di dati dove, come con ISNULL, il tipo di dati non è influenzato dalla precedenza del tipo di dati.
  2. Prendi in considerazione le seguenti istruzioni sql

    DECLARE @c5 VARCHAR(5);
    SELECT 'COALESCE', COALESCE(@c5, 'longer name')
    UNION ALL
    SELECT 'ISNULL',   ISNULL(@c5,   'longer name');
    

Risultati:

COALESCE longer name
ISNULL   longe

Ciò accade perché ISNULL accetta il tipo di dati del primo argomento, mentre COALESCE controlla tutti gli elementi e sceglie la soluzione migliore (in questo caso, VARCHAR (11))

Per una spiegazione più dettagliata sulla decisione tra COALESCE vs ISNULL, controllare questo: https://www.mssqltips.com/sqlservertip/2689/deciding-between-coalesce-and-isnull-in-sql-server/

2

Dove esiste una sola condizione nulla, ISNULL avrà un sovraccarico minore. Tuttavia, la differenza è probabilmente trascurabile.

2
James Johnson

NULL e COALESCE non sono sempre intercambiabili. Merita di conoscere le loro differenze per sapere quando è meglio usare l'una sull'altra:

enter image description here

La tabella sopra è il confronto tra ISNULL e COALESCE dal libro Exam Ref 70-761 Querying Data with Transact-SQL Scritto da Itzik Ben-Gan.


  1. Numero di parametri supportati - 2 Per ISNULL vs >2 Quando si utilizza COALESCE
  2. ISNULL è una funzionalità T-SQL proprietaria e COALESCE è standard SQL ISO/ANSI
  3. Il tipo di dati del risultato è importante. Dopo aver letto le note nella tabella sopra, controlla i seguenti casi:

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

    enter image description here

    ISNULL sta ottenendo il tipo di dati del primo argomento in quanto non è NULL letterale. È VARCHAR(3) ed è un risultato, i dati del secondo argomento vengono tagliati per abbinarli. Con COALESCE il tipo di dati se viene utilizzata la precedenza più alta.

    DECLARE @x VARCHAR(8)  = '123x5'
           ,@y INT = 123;
    
    SELECT ISNULL(@x, @y) AS [ISNULL];
    SELECT COALESCE(@x, @y) AS [COALESCE];
    

    enter image description here

    enter image description here

    ISNULL sta restituendo il tipo di dati del primo argomento, mentre in COALESCE stiamo ricevendo errori, poiché INT ha la precedenza più alta e la conversione del valore del primo argomento in INT non riesce.

  4. Anche la nullità del risultato può essere importante. Per esempio:

    DECLARE @x VARCHAR(3) = NULL
           ,@y VARCHAR(3) = NULL;
    
    DROP TABLE IF EXISTS [dbo].[DataSource01];
    
    SELECT ISNULL(10, 20) AS [C1]
          ,ISNULL(@x, 'text') AS [C2]
          ,ISNULL(@x, @y) AS [C3]
    INTO [dbo].[DataSource01];
    
    DROP TABLE IF EXISTS [dbo].[DataSource02];
    
    SELECT COALESCE(10, 20) AS [C1]
          ,COALESCE(@x, 'text') AS [C2]
          ,COALESCE(@x, @y) AS [C3]
    INTO [dbo].[DataSource02];
    

    Controlliamo la proprietà Nullable di ogni colonna:

    enter image description here

    enter image description here

    Usando COALESCE abbiamo una proprietà NOT NULL Della colonna impostata su Yes, solo quando tutti gli input non sono nulli.

  5. Secondo lo standard SQL, l'espressione COALESCE viene tradotta in:

    CASE WHEN (<subquery>) IS NOT NULL THEN (<subquery>) ELSE 0 END
    

    Se il risultato dell'esecuzione della sottoquery nella clausola WHEN non è NULL, SQL Server lo esegue una seconda volta nella clausola THEN. In altre parole, in tal caso lo esegue due volte. Solo se il risultato dell'esecuzione nella clausola WHEN è NULL, SQL Server non esegue nuovamente la sottoquery, ma restituisce l'espressione ELSE. Pertanto, quando si utilizzano le subquery, la funzione ISNULL ha un vantaggio in termini di prestazioni.

1
gotqn