条件在WHERE子句中TSQL,运营商的问题

问题描述:

在SQL Server查询我想有一个条件WHERE条款是这样的:条件在WHERE子句中TSQL,运营商的问题

WHERE id_A = CASE WHEN @id != 0 THEN @id ELSE anything but @id END 

我不知道该怎么写ELSE部分。在一种情况下,我需要WHERE id_A = @id,但 WHERE id_A != @idELSE

感谢您的帮助。

假设id_a不能为空

WHERE id_a = CASE 
       WHEN @id = 0 THEN CASE 
            WHEN id_a <> 0 THEN id_a 
            END 
       ELSE @id 
       END 

应该这样做。除非您使用OPTION RECOMPILEare on specific versions of SQL Server 2008,否则这将是低效的。

--will match always (if id_A can not be NULL 
WHERE 
    id_A = CASE WHEN @id <> 0 THEN @id ELSE id_A END 

-- will be false always 
WHERE 
    id_A = CASE WHEN @id <> 0 THEN @id ELSE NULL END 

这些可以写成

WHERE 
    id_A = ISNULL(NULLIF(@id, 0), id_A) 

WHERE 
    id_A = NULLIF(@id, 0) 

尝试沿着这一线的东西:

WHERE (@id != 0 AND id_A = @id) OR (@id = 0 AND id_A != @id) 

注意,如果查询可能返回显著不同的行数,那么你应该而应考虑将其分为两个查询,以确保您对这两个查询都有最佳查询计划,这些查询计划如下:

IF @id != 0 THEN 
BEGIN 
    SELECT /* columns from table */ 
    WHERE id_A = @id 
END 
ELSE 
BEGIN 
    SELECT /* columns from table */ 
    WHERE id_A != 0 
END 

不幸的是,这意味着复制了其余的SQL查询,但是在一个变体返回大部分表的情况下它可能会更好地执行,但是第一个变体只返回单个行。

+1

@Martin谢谢 - 这将教我如何在没有检查的情况下发布代码实际运行! – Justin 2011-04-11 11:05:06

+0

非常感谢Kragen您的“单线”解决方案对于我想要做的事情完美地工作,我没有考虑它,但它终于简单 – benj007 2011-04-11 13:39:26