Больше, чем в SQL CASE-заявлении

Мне сложно определить больше, чем в инструкции SQL.

Здесь мой код:

select one, two three from orders
where case when @orderid > 0 then orders.orderid = @orderid end

@orderid - это параметр, переданный хранимой процедуре. Идея состоит в том, что если действительный ( > 0) orderid передан, то используйте его как фильтр в предложении where, иначе не используйте его все.

Ответы

Ответ 1

У Гуффа есть правильный ответ, но так, как вы это делали, используя трюк CASE (который иногда пригодится):

--If order ID is greater than 0, use it for selection
--otherwise return all of the orders.
select one, two, three
from orders
where orders.orderid = CASE
    WHEN @orderid > 0 then @orderid
    ELSE orders.orderid
END

CASE всегда должен что-то возвращать, поэтому, если вы хотите условно отключить инструкцию в своем предложении WHERE и не можете использовать OR, вы можете просто установить значение, равное себе, и это всегда должно быть правдой (кроме при сравнении нулей).

Изменить: я должен также сказать, что в таких запросах, где количество строк, которые могут быть возвращены, может сильно варьироваться (одна строка против всей таблицы), использование подсказки OPTION (RECOMPILE) может значительно повысить производительность однорядный корпус.

Ответ 2

Ответ NYCDotnet, как и остальные ответы, работает, но они могут быть SARGable

Сделать этот запрос без SARGable.

select one, two three from orders
where 
     case 
     when @orderid > 0 then orders.orderid  
     else 0
     end = @orderid

.. SARGable, сделайте это вместо этого:

select one, two three from orders
where 
     @orderid > 0 and orders.orderid = @orderid

     or not (@orderid > 0)

Если @orderid никогда не станет отрицательным, просто упростите решение:

select one, two three from orders
where 
     @orderid > 0 and orders.orderid = @orderid

     or @orderid = 0

Или еще лучше, т.е. если @orderid не станет отрицательным:

select one, two three from orders
where 
     @orderid = 0

     or orders.orderid = @orderid

Ответ 3

Здесь вам не нужно использовать CASE. Та же логика, немного переделанная:

select one, two three from orders
where @orderid is null or @orderid <= 0 or orders.orderid = @orderid

Ответ 4

Вы не можете использовать условие как значение в выражении case.

Вы можете просто использовать оператор or, чтобы условие не использовалось для недопустимых значений:

select one, two, three from orders
where @orderid <= 0 or orders.orderid = @orderid

Ответ 5

IF @orderid < 0
   BEGIN
      RETURN
   END

  SELECT one, two, three 
  FROM orders 
  WHERE orders.orderid = @orderid 

Фактически, поскольку id является int и если его столбец идентичности всегда будет больше нуля, вам действительно не нужно даже проверять, больше ли @orderid больше нуля. При этом указанный выше код будет поддерживать выполнение запроса с недопустимым идентификатором заказа.

Вы также можете сделать это таким образом

SELECTone, two, three

FROM orders

WHERE orderid = @orderid AND @orderid > 0