在SQL Server中执行CASE where where子句的最佳方法

时间:2014-08-20 21:00:39

标签: sql-server

我正在尝试构建一个SQL SP来执行查询报告。它有几个参数可以是NULL或应该有一个值。我正在使用下面的代码。还有另一种替代方法,更干净或更合适。我假设如果Argument为Null,我只会做1 = 1的过滤条件。

DECLARE @Arg1 VARCHAR(10) = NULL,
        @Arg2  VARCHAR(10) = NULL

SELECT * FROM Table1
WHERE 
(CASE WHEN (@Arg1 IS NULL) THEN
        1
    ELSE
        @Arg1 
    END) = 
    (CASE WHEN (@Arg1 IS NULL) THEN
        1
    ELSE
        Location
    END)
AND
    (CASE WHEN (@Arg2 IS NULL) THEN
        1
    ELSE
        @Arg2 
    END) = 
    (CASE WHEN (@Arg2 IS NULL) THEN
        1
    ELSE
        Sex
    END)

3 个答案:

答案 0 :(得分:4)

你不能这样做吗?

where 
(@Arg1 is null or @Arg1 = Location)
and
(@Arg2 is null or @Arg2 = Sex)

然后,如果@Arg1(或2)为null,那么谓词的那一部分为TRUE,而and' d为下一个谓词。

答案 1 :(得分:4)

另一种可能性,即使更短,是使用Coalesce()

where COALESCE(@Arg1, Location) = Location
  and COALESCE(@Arg2, Sex) = Sex

也就是说,当@ arg1和@ arg2有值时,使用它们,否则,使用有问题的列;因为Location = Location始终为真(至少在不是NULL时,在您自己的代码中也是同样的问题)。

答案 2 :(得分:1)

另一种可能性是

where IsNull(@Arg1,Location) = Location
  and IsNull(@Arg2, Sex) = Sex

这几乎是@IFLoop的答案,但IsNull略快于COALESCE

Which is quicker COALESCE OR ISNULL?


运行以下查询(在我的机器中):

DECLARE @ARG1 VARCHAR(50) = 'xserver_name'

select *
from sys.tables
where IsNull(@Arg1, name) = name

费用:27%

select *
from sys.tables
where Coalesce(@Arg1,name) = name

费用27%

select *
from sys.tables
where (@Arg1 is null or @Arg1 = name)

费用45%

请运行并查看执行计划


但是如果表的行数增加,差异消失,因为是由表扫描时间占主导地位:

select *
from sys.all_Columns
where IsNull(@Arg1, name) = name

费用:33%

select *
from sys.all_Columns
where Coalesce(@Arg1,name) = name

费用34%

select *
from sys.all_Columns
where (@Arg1 is null or @Arg1 = name)

成本33%