在SQL中检查两个日期之间或为NULL的日期

3

我希望能够使用存储过程检查两个日期之间的日期或者可以传递一个NULL参数。

代码

declare @fromDate date = null
declare @toDate date = null

select * from Mytable 
where date betweeen @fromDate and @toDate OR NULL (how to check for both parameters)

我还有另外两个参数,因此无论日期如何,都应该显示结果。 如果@todate和@fromDate为空,请帮忙。

如果@toDate为空,你需要什么结果? - Kaf
我还有另外两个参数,所以无论日期如何,结果都应该显示。 - Neo
3个回答

11

尝试使用以下 coalesce 函数:

declare @fromDate date = null
declare @toDate date = null

select * from Mytable 
where date between coalesce(@fromDate,date) and coalesce(@toDate,date)

@parado 测试这个对于日期等于@fromDate@toDate的情况不起作用,只能严格使用<或>。- 因此,@fromDate必须是-1天或toDate + 1天。- 如果我理解正确的话。 - Pakk
@Pakk 我不知道你的情况,但我检查了上面的解决方案 - 它有效。 - Robert
@Parado 我已经找到原因了 - 是我的错。我的日期是通过 Date + '00:00:00:0000' 到 Date + '00:00:00:0000' 进行查找的,我漏掉了 timeSpan。感谢您提供的代码。 - Pakk

1
相当于将您的英语转换为SQL:
where (date is null or date betweeen @fromDate and @toDate)

1
不确定,但我认为OP的意思是参数可以为空,而不是日期字段。 - Kaf
那个语法不起作用,我已经使用了COALESCE而不是IS NULL :) - Neo

0

当我在使用"between""coalesce"之外的更好解决方案时,我发现了这个线程:

  • firebird SQL
  • 参数永远不会为空
  • createdatum永远不会为空
  • offdatum可以为空 - 显然是为了某些原因 ;)

最初的解决方案:

where
    X = :X
    AND
    cast(:QryDateTime as DATE) between
      createdatum and coalesce(offdatum, cast(:QryDateTime as DATE))

问题有点棘手:当将“now”作为QryDateTime的值时,有时会找不到结果 - 即使应该存在一个结果。

问题在于每次都单独评估“now”,显然不是从左到右的顺序。

最终我将其更改为:

where
    X = :X
    AND
    iif(offdatum is null, 1, iif(offdatum > cast(:QryDateTime as DATE), 1, 0)) = 1
    AND
    cast(:QryDateTime as DATE) > createdatum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接