Оператор CASE в предложении where с использованием равенства и IN

WHERE CONDITION1='ABC'
AND Status =
    CASE  @Option 
            WHEN 1 THEN 'True'
            WHEN 2 THEN 'False'
            WHEN 3 THEN  NULL
            WHEn 4 THEN **IN ('True', 'False', NULL)**
    END

Как мне написать запрос, в котором мои первые варианты совпадают напрямую, используя =, но мой последний вариант требует IN

Приведенный выше запрос дает ошибку, но я хочу что-то похожее на нее, чего я не могу узнать.


person user1820973    schedule 19.11.2012    source источник
comment
какую базу данных вы используете?   -  person Ankur    schedule 19.11.2012
comment
Вы не можете напрямую сравнивать с NULL, как вы пытаетесь сделать в своем выражении IN, поскольку NULL означает неизвестно. Для этого вам понадобится отдельный оператор, использующий IS NULL.   -  person Bridge    schedule 19.11.2012


Ответы (2)


Оператор CASE не может вернуть набор значений... но этот запрос должен дать вам те же результаты:

WHERE CONDITION1='ABC'
AND Status =
    CASE  
        WHEN 1 THEN 'True'
        WHEN 2 THEN 'False'
        WHEN 3 THEN NULL
        WHEN 4 THEN Status
    END

Кроме того, обратите внимание, что если у вас нет ANSI_NULLS OFF, Status никогда не будет = NULL... вам нужно будет использовать IS NULL для этого сравнения, и вам нужно вообще отказаться от оператора CASE.

person Michael Fredrickson    schedule 19.11.2012
comment
+1 за скрытность... Мне нравится, как вы используете Status, чтобы охватить все три возможных варианта. -0,4 за то, что не сразу видно, что делает код. Итого: +0,6, округляется до +1. :-) - person James Cronen; 19.11.2012
comment
Что, если статус равен чему-то не одному из этих вариантов? - person PinnyM; 19.11.2012
comment
@PinnyM Затем он попытается выполнить сравнение с NULL точно так же, как в случае с 3 здесь. - person Bridge; 20.11.2012
comment
@Bridge, я хотел сказать, что если @Option = 4 и status = 'foo', он будет оцениваться как логическое значение true, в то время как исходный псевдоалгоритм был бы false. Возможно, это не проблема для ОП, но этот сценарий не рассматривался... - person PinnyM; 20.11.2012

Пропустите оператор CASE и используйте ИЛИ. И согласно стандарту ANSI не сравнивать с NULL:

WHERE CONDITION1='ABC'
AND ((@Option = 1 AND Status = 'True') OR
     (@Option = 2 AND Status = 'False') OR
     (@Option = 3 AND Status IS NULL) OR
     (@Option = 4 AND (Status IS NULL OR Status IN ('True', 'False'))))
person PinnyM    schedule 19.11.2012