如果日期时间参数为 null,则分配日期时间值



我有一个SSRS报告,其中包括开始和结束日期参数。 对于开始日期和结束日期,可以设置选项 NULL。 规则是,如果开始日期为 null,则检索的数据从时间开始。 如果结束日期为 null,则将其设置为今天的日期。 这就是我在这里尝试做的事情:

SELECT * 
FROM mytab 
WHERE (Start >= CASE @From 
WHEN NULL 
THEN DATEADD(year, -100, @From)
END) 
AND (End <= CASE @To
WHEN NULL THEN GETDATE()
END)

作为测试,我在查询中声明变量@From和@To,将它们设置为 NULL 并在 SSMS 上运行它。

我想实现的是说如果@From为空,则将值设置为 100 年前,并将其与 mytab 字段"开始"进行比较。同样,如果@To为 null,请将其设置为今天的日期并与"结束"进行比较。 但是,这不会返回任何数据。 这显然是错误的,那么正确的方法是什么?

这里不需要使用 CASE 语句,因为我们可以使用 ISNULL 或 COALESCE。

SELECT * 
FROM mytab 
WHERE Start >= ISNULL( @From , DATEADD(year, -100, GETDATE()) ) 
AND End   <= ISNULL( @To   , GETDATE() )

CASE 语法不会像您想要的那样解析 NULL。

DECLARE @TEST AS VARCHAR(10)
SET @TEST = NULL
SELECT CASE WHEN @TEST IS NULL THEN 1 ELSE 0 END AS TEST1, 
CASE @TEST WHEN NULL THEN 1 ELSE 0 END AS TEST2

TEST1 的结果为 1,TEST2 的结果为 0 - 而不是预期的 1 和 1。

SELECT * from mytab WHERE (Start >= CASE WHEN @From IS NULL THEN DATEADD(year, -100, @From) END) 
AND (End <= CASE WHEN @To IS NULL THEN GETDATE() END)

一个简单的case表达式when子句不能匹配null,但你可以在搜索的case中使用is null来测试它:case when @From is NULL then Cast( '1900-01-01' as Date ) else @From end。请注意,如果when子句都不匹配,则else子句将提供一个值。

针对您的问题的一个更整洁的解决方案是使用Coalesce

select *
from MyTab
where Coalesce( @From, Cast( '1900-01-01' as Date ) ) <= [Start] and
[End] <= Coalesce( @To, Cast( GetDate() as Date ) );

请注意,该值被强制转换为date以消除一天中的时间。

最新更新