使用case检查where子句中的变量是否为null

时间:2015-11-03 10:30:39

标签: sql sql-server

我在MSSQL 2中声明了可以null的变量:

DECLARE @startCheckDate VARCHAR(10) = '2015-10-20'  --this can be null
DECLARE @endCheckDate VARCHAR(10) = '2015-10-31' -- this can be null

变量既可以是null,也可以是null两种选择。

现在我的查询中的where条件我想使用null检查这些值是case我正在尝试:

declare @since varchar(10) = '2015-10-20' --this is never null so it do not matter

select doc.id 
from document 
where
doc.active = 'T'
and 
(
case when @startCheckDate is not null and @endCheckDate is not null
then
    doc.modifiedDate > @since or (doc.modifiedDate between @startCheckDate and @endCheckDate)
else
    doc.modifiedDate > @since
end)

3 个答案:

答案 0 :(得分:1)

如果我对此问题的理解是正确的,您可以使用OR子句中的WHERE条件执行此操作,而不是使用CASE

注意:您应将DATE值作为日期进行比较。我添加了转换以将值从字符串更改为DATE值,但如果值在变量的第一位置为DATE,并且您要与之比较的列,则会更容易

SELECT  doc.id
FROM    document
WHERE   doc.active = 'T'
        AND ( -- compare doc.modifiedDate > @since if start and end dates NULL
              ( @startCheckDate IS NULL
                AND @endCheckDate IS NULL
                AND CONVERT(DATE, doc.modifiedDate) > CONVERT(DATE, @since)
              )
              OR ( -- use between if start and end dates not NULL
                   @startCheckDate IS NOT NULL
                   AND CONVERT(DATE, doc.modifiedDate) 
                       BETWEEN CONVERT(DATE, @startCheckDate) 
                           AND CONVERT(DATE, @endCheckDate)
                 )
            )

看看你的代码,看起来你的IS NULLIS NOT NULL检查错误的方式,我在我的样本中交换过。

这样,只评估符合条件的WHERE子句部分。

答案 1 :(得分:0)

在SQL中,当我需要动态构建where子句时,我构建查询并使用Exec运行它。它帮助我减少所有这些在性能方面可能很昂贵的案例陈述。类似下面的东西。这样就可以动态构建where子句

declare @since varchar(10) = '2015-10-20' --this is never null so it do not matter
declare @sql nvarchar(max) = ''

if @startCheckDate is not null and @endCheckDate is not null
begin
    set @sql = 'select doc.id from document where doc.active = ''T'' and doc.modifiedDate > ' + @since + ' or (doc.modifiedDate between ' + @startCheckDate + ' and ' + @endCheckDate + ')' 
end
else 
begin
    set @sql = 'select doc.id from document where doc.active = ''T'' and  doc.modifiedDate > ' + @since     
end
exec (@sql)

答案 2 :(得分:-2)

对null的任何比较都是false,因此不需要这种情况

( doc.modifiedDate > @since or doc.modifiedDate between @startCheckDate and @endCheckDate )