2009-05-13 2 views
4

Помимо читаемости есть ли какое-либо существенное преимущество в использовании оператора CASE WHEN против ISNULL/NULLIF при защите от деления на ошибку 0 в SQL?Microsoft SQL: CASE WHEN vs ISNULL/NULLIF

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

против

ISNULL((EndingQuantity)/NULLIF(BeginningQuantity + BAdjustedQuantity,0),0) 

ответ

7

Помните, что NULL отличается от 0. Таким образом, два фрагмента кода в вопросе может возвращать разные результаты тот же вход.

Например, если BeginningQuantity является NULL, то первое выражение имеет значение NULL:

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

Теперь (? NULL, +), равен NULL, то и NULL = 0 является ложным, так что условие ELSE оценивается, что дает ?/(NULL +?), Что приводит к NULL. Однако второе выражение становится следующим:

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

Здесь NULL +? становится NULL, а поскольку NULL не равно 0, NULLIF возвращает первое выражение, которое равно NULL. Внешняя ISNULL улавливает это и возвращает 0.

Итак, решите: вы защищаете от деления на ноль или деление на NULL? ;-)

+0

Я в конечном счете, пытаясь защитить от деления на 0 –

+0

Стоимость разделения затмит стоимость любой случай или IsNull проверок, поэтому я бы наиболее читаемый решение. Другой вариант - предложение WHERE, чтобы исключить строки, которые будут делить на ноль. – Andomar

0

На мой взгляд, с помощью IsNull/NULLIF быстрее, чем при использовании случае, когда. Я скорее isnull/nullif.

3

В вашем примере я думаю, что производительность пренебрежимо мала. Но в других случаях, в зависимости от сложности вашего делителя, ответ «зависит от».

Here is an interesting blog по теме:

Для удобства чтения, мне нравится чехол/Когда.

0

Я хотел бы использовать ISNULL, но попробуйте отформатировать его, чтобы он показывает смысл лучше:

SELECT 
    x.zzz 
     ,x.yyyy 
     ,ISNULL(
        EndingQuantity/NULLIF(BeginningQuantity+BAdjustedQuantity,0) 
       ,0) 
     ,x.aaa 
    FROM xxxx... 
0
CASE WHEN (coalesce(BeginningQuantity,0) + coalesce(BAdjustedQuantity,0))=0 THEN 0 ELSE coalesce(EndingQuantity,0)/(coalesce(BeginningQuantity,0) + coalesce(BAdjustedQuantity,0)) END 

ваш лучший вариант имхо

0

К сожалению, здесь есть немного больше упростить upbuilded запрос 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]