我想搜索From Date
和To Date
。这是一个两场搜索。当我在字段From Date
中输入日期并将字段To Date
留空时,我必须在From Date
和Date Now
之间收到结果。但是当我写To Date
并将字段From Date
留空时,我必须收到所有记录,直到书面日期(写在字段To Date
中)。
如何为此编写正确的SQL? 我到目前为止写了这个:
`WHERE (@FromDate is null or CN.[FromDate] between Cast(@FromDate as date) AND Cast(@ToDate as date))`
然而,目前没有任何事情发生。
答案 0 :(得分:1)
请勿使用between
。相反,将比较分为两部分:
WHERE (@FromDate is null or CN.FromDate >= Cast(@FromDate as date)) AND
(@ToDate is null or CN.FromDate <= Cast(@ToDate as date));
如果@FromDate
和@ToDate
被声明为date
,则无需cast()
。
编辑:
如果您在FromDate
上有索引并且您的日期在合理的值范围内,则以下内容更具“sargable”:
WHERE CN.FromDate >= coalesce(@FromDate, '1950-01-01') and
CN.ToDate < coalesce(@ToDate, '2100-01-01')
编辑II:
日期的比较操作可能很危险,因为日期有时可能包含时间组件(如果您的变量实际上是datetime
。这意味着编写原始代码的更安全的方法是:
WHERE (@FromDate is null or CN.FromDate >= Cast(@FromDate as date)) AND
(@ToDate is null or CN.FromDate < dateadd(day, 1, Cast(@ToDate as date)));
这意味着即使FromDate
是带有时间成分的datetime
,它也能直观地工作。
所有操作都在常量上,因此SQL Server可以在列上使用索引。
答案 1 :(得分:0)
您可以尝试使用COALESCE在一行中写下所有内容:
WHERE CN.FromDate >= COALESCE(@FromDate, CN.FromDate) AND CN.ToDate <= COALESCE(@ToDate, CN.ToDate)