Microsoft SQL: il CASO QUANDO vs ISNULL/NULLIF

Oltre leggibilità c’è qualche significativo beneficiare di utilizzo di un CASO in cui la dichiarazione vs ISNULL/NULLIF in guardia contro una divisione per 0 errore in SQL?

CASE WHEN (BeginningQuantity + BAdjustedQuantity)=0 THEN 0 
ELSE EndingQuantity/(BeginningQuantity + BAdjustedQuantity) END

vs

ISNULL((EndingQuantity)/NULLIF(BeginningQuantity + BAdjustedQuantity,0),0)
Per rispondere alla intitolato domanda: NULLIF è implementato come un CASO in cui, in modo è possibile formulare un CASO che esegue in modo identico in entrambi i tempi e i risultati. ISNULL, tuttavia, è una funzione intrinseca. Dato ISNULL(<exp1>,<exp2>), <exp1> non è valutata due volte quando non null – una prodezza che non è possibile duplicare l’utilizzo di CASI QUANDO. Inoltre il tipo di dati restituito dalla funzione ISNULL può essere diverso da un CASO di attuazione. Dal COALESCE è implementato utilizzando CASO QUANDO i suoi risultati, la corrispondenza di un CASO in cui attuazione, piuttosto che una (possibilmente nidificati) ISNULL di simulazione.

OriginaleL’autore Christopher Klein | 2009-05-13

6 Replies
  1. 7

    Ricordare che NULL è diverso da 0. Così i due frammenti di codice in questione può restituire risultati diversi per lo stesso ingresso.

    Per esempio, se BeginningQuantity è NULL, la prima espressione restituisce NULL:

    CASE WHEN (NULL + ?)=0 THEN 0 ELSE ?/(NULL + ?) END

    Ora (NULL + ?) è uguale a NULL, NULL=0 è falso, quindi, la clausola ELSE viene valutato, dando ?/(NULL+?), il cui risultato è NULL. Tuttavia, secondo l’espressione diventa:

    ISNULL((?)/NULLIF(NULL + ?,0),0)

    Qui NULL+? diventa NULLO, e perché NULL non è uguale a 0, il NULLIF restituisce la prima espressione, che è NULL. L’esterno ISNULL catture questo e restituisce 0.

    Quindi, rendere la vostra mente: sono in guardia contro la divisione per zero, o divisione NULL? 😉

    Sono, in definitiva, cercando di proteggere la divisione per 0
    Il costo della divisione nano a costo di qualsiasi CASO o ISNULL controlli, quindi mi piacerebbe prendere più leggibile soluzione. Un’altra opzione è una clausola WHERE per escludere righe di divisione per zero.

    OriginaleL’autore Andomar

  2. 3

    Nel tuo esempio credo che le prestazioni è trascurabile. Ma in altri casi, a seconda della complessità del divisore, la risposta è ‘dipende’.

    Ecco un interessante blog sul tema:

    Per migliorare la leggibilità, mi piace il Quando.

    OriginaleL’autore Jeff Hall

  3. 0

    A mio parere, utilizzando la funzione Isnull/Nullif è più veloce rispetto al Caso Quando. Io invece isnull/nullif.

    OriginaleL’autore Eric

  4. 0

    Vorrei utilizzare la funzione ISNULL, ma provare a formattare in modo che esso mostra il significato di meglio:

    SELECT
        x.zzz
            ,x.yyyy
            ,ISNULL(
                       EndingQuantity / NULLIF(BeginningQuantity+BAdjustedQuantity,0)
                    ,0)
            ,x.aaa
        FROM xxxx...

    OriginaleL’autore KM.

  5. 0
    CASE WHEN (coalesce(BeginningQuantity,0) + coalesce(BAdjustedQuantity,0))=0 THEN 0 ELSE coalesce(EndingQuantity,0)/(coalesce(BeginningQuantity,0) + coalesce(BAdjustedQuantity,0)) END

    la scelta migliore imho

    OriginaleL’autore DForck42

  6. 0

    Mi dispiace, qui è un po ‘ più di semplificare upbuilded query sql.

    SELECT 
    
    (ISNULL([k1],0) + ISNULL([k2],0)) /
    
    CASE WHEN (
    (
       CASE WHEN [k1] IS NOT NULL THEN 1 ELSE 0 END +
       CASE WHEN [k2] IS NOT NULL THEN 1 ELSE 0 END
    ) > 0 )
    THEN
    (
      CASE WHEN [k1] IS NOT NULL THEN 1 ELSE 0 END +
      CASE WHEN [k2] IS NOT NULL THEN 1 ELSE 0 END
    )
    ELSE 1 END
    
    FROM dbo.[Table]

    OriginaleL’autore Andrew

Lascia un commento