我很难找到比SQL语句更大的内容。
这是我的代码:
select one, two three from orders
where case when @orderid > 0 then orders.orderid = @orderid end
@orderid是传递给存储过程的参数。这个想法是,如果传递了一个有效的(> 0)orderid,那么将它用作where子句中的过滤器,否则不要全部使用它。
答案 0 :(得分:20)
Guffa有正确的答案,但你使用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)提示可能有助于提高性能。单排案例。
答案 1 :(得分:4)
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
答案 2 :(得分:3)
您无需在此处使用CASE
。同样的逻辑,重新安排了一点:
select one, two three from orders
where @orderid is null or @orderid <= 0 or orders.orderid = @orderid
答案 3 :(得分:3)
您不能将条件用作case
表达式中的值。
您可以使用or
运算符将条件用于无效值:
select one, two, three from orders
where @orderid <= 0 or orders.orderid = @orderid
答案 4 :(得分:0)
IF @orderid < 0
BEGIN
RETURN
END
SELECT one, two, three
FROM orders
WHERE orders.orderid = @orderid
事实上,因为id是一个int,如果它是一个标识列,它总是大于零,所以你甚至不需要费心去检查@orderid是否大于零。也就是说,上面的代码将使查询无法使用无效的订单ID运行。
你也可以这样做
SELECTone, two, three
FROM orders
WHERE orderid = @orderid AND @orderid > 0