如何在BETWEEN子句中包含空值?

时间:2014-07-22 07:09:19

标签: sql sql-server sql-server-2008

在我的查询的where子句中,我有条件:

User.DateOfBirth BETWEEN @startDate AND @endDate 

@startDate@endDate可以为空的地方。如果@startDate为空,我希望所有值小于或等于@endDate;如果@endDate为空,我希望所有值都大于或等于@startDate;如果两者都为null我想要所有值。

我失败的尝试 - 返回0结果

((( User.DateOfBirth > @startDate) OR (@startDate Is null)) AND  (( User.DateOfBirth < @endDate) OR (@endDate is null)) )

(编者注:BETWEEN包括端点(小于/大于或等于),但空案例的描述没有。我认为这是一个监督。

5 个答案:

答案 0 :(得分:10)

试试这个:

[User].DateOfBirth BETWEEN ISNULL(@startDate,[User].DateOfBirth) AND ISNULL(@endDate,[User].DateOfBirth)

答案 1 :(得分:2)

我想到了两种方法:

分别将四个案例分开,然后将它们合并在一起:

  1. start和end为null:任何日期匹配,
  2. start为null,因此需要DoB&lt; = end
  3. send为null,因此需要DoB&gt; = start
  4. 既不是null,也需要
  5. 之间

    这将导致长篇大论。

    使用IsNull

    正如mehdi lotfi在answer中所示。

答案 2 :(得分:1)

如果您使用的是可以为空的日期时间类型,则可以使用

User.DateOfBirth BETWEEN isnull(@startDAte, CAST('1753-01-01' AS datetime)) AND isnull(@endDAte, CAST('9999-12-31' AS datetime))

用于datetime2使用

User.DateOfBirth BETWEEN isnull(@startDAte, CAST('0001-01-01' AS datetime2)) AND isnull(@endDAte, CAST('9999-12-31' AS datetime2))

答案 3 :(得分:0)

试试这个:

select * from yourtable
where 
(@startdate is null and @enddate is null)
or
(@startdate is null and @enddate is not null and User.DateOfBirth <= @enddate)
or
(@startdate is not null and @enddate is null and User.DateOfBirth >= @startdate)
or
(@startdate is not null and @enddate is not null and User.DateOfBirth BETWEEN @startdate AND @enddate)

这解决了所有可能的情况:

  • 两个参数均为null - 返回所有结果
  • 仅限非空结束日期 - 返回DOB <=结束日期
  • 的所有结果
  • 仅限非空开始日期 - 返回DOB&gt; =开始日期
  • 的所有结果
  • 两个参数都为非null - 返回DOB在开始日期和结束日期之间的所有结果

答案 4 :(得分:0)

WHERE

((User.DateOfBirth BETWEEN @startDAte AND @endDAte) AND @startDAte is not null AND @endDAte is not null)
OR
((User.DateOfBirth =< @endDAte) AND @startDAte is null AND @endDAte is not null)
OR 
 ((User.DateOfBirth >= @startDAte) AND @startDAte is not null AND @endDAte is  null)
OR 
(1=1 AND @startDAte is null AND  @endDAte is  null)