Условия в пунктах Где, основанных на флаге - PullRequest
3 голосов
/ 28 марта 2012

Могу ли я использовать флаг, чтобы выбрать другое предложение WHERE?Как то так.

SELECT  fields
 from T3 t3 
left outer join T1 t1 on T1.Id=t2.Id
WHERE 
    CASE 
        WHEN @Status <> 1 
        THEN (t3.Id = @SId AND sh.StatusId = 3 AND k.StatusId = 1)
        ELSE t2.Id = @SID AND  t2.StatusID = 12
GROUP BY whatever

Ответы [ 5 ]

2 голосов
/ 28 марта 2012

зачем тебе дело, когда?Вы можете просто сделать ГДЕ Статус <> 1 И ... ИЛИ ...?

1 голос
/ 28 марта 2012

Я не думаю, что @JBrooks правильно перевел ваше заявление (и, что неприятно, может привести к ложным срабатываниям).

Я думаю, что CASE эквивалент выглядит следующим образом:

WHERE 1 = CASE 
             WHEN @Status <> 1 
             THEN CASE 
                     WHEN (t3.Id = @SID AND sh.StatusId = 3 AND k.StatusId = 1) 
                     THEN 1 
                  END
             ELSE CASE 
                     WHEN t2.Id = @SID AND t2.StatusID = 12 
                     THEN 1 
                  END 
          END

Однако я согласен с тем, что такую ​​конструкцию трудно читать и отлаживать, и согласен с тем, что она может быть преобразована.Однако, хотя «предпочтительный путь» @ JBrooks представляет собой дизъюнктивную нормальную форму (то есть (predicate_1 OR predicate_2), которая требует скобок), я предпочитаю конъюнктивную нормальную форму (то есть preidcate_1 AND preidcate_2), например,

WHERE
( p.Status = 1 OR ( t3.Id = p.SID AND sh.StatusId = 3 AND k.StatusId = 1 ) )
AND
( p.Status <> 1 OR ( t2.Id = p.SID AND t2.StatusID = 12 ) )
1 голос
/ 28 марта 2012

предпочтительный способ:

    WHERE
    (@Status <> 1 AND t3.Id = @SId AND sh.StatusId = 3 AND k.StatusId = 1)
    OR (t2.Id = @SID AND t2.StatusID = 12)

или это немного проще для чтения оператора case:

WHERE
CASE WHEN @Status <> 1 
       AND t3.Id = @SId 
       AND sh.StatusId = 3 
       AND k.StatusId = 1 THEN 1
WHEN t2.Id = @SID 
       AND t2.StatusID = 12 THEN 1
ELSE 0 END = 1
1 голос
/ 28 марта 2012

Конечно.CASE возвращает значение, поэтому использование будет примерно таким:

where case
  when @Mode = 1 and A.Foo = B.Foo then 1
  when @Mode = 2 and A.Foo > B.Foo + 5 then 1
  when A.Bar < @Mode then 1
  else 0
  end = 1
1 голос
/ 28 марта 2012

Вы можете - просто добавьте END к CASE.

SELECT  fields
FROM    T3 t3 
LEFT OUTER JOIN T1 t1 on T1.Id=t2.Id
WHERE 
        CASE 
          WHEN @Status <> 1 THEN 
            (t3.Id = @SId AND sh.StatusId = 3 AND k.StatusId = 1)
           ELSE 
            t2.Id = @SID AND  t2.StatusID = 12
        END
GROUP BY whatever
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...