正如标题所说,我已经获得了合同结束日期的表数据,我需要返回结束日期在15到20天之间的所有行的列表。我有以下代码:
WHERE (DATEDIFF([day], Contract.EndDate, GETDATE()) < 20)
AND (Contract.EndDate < DATEADD([day], 15, GETDATE()))
答案 0 :(得分:2)
您的查询将返回contract.endate
从现在起不到20天的行。试试这个where
条款
DATEDIFF([day], Contract.EndDate, GETDATE()) between 15 and 20
答案 1 :(得分:2)
这写得更好:
WHERE Contract.EndDate >= DATEADD(DAY, 15, GETDATE())
AND Contract.EndDate < DATEADD(DAY, 21, GETDATE())
注意我假设您想要包含第20天的内容,所以在GETDATE()
添加了21天,如果这是一个不正确的假设,那么只需将其更改为20 < / p>
这样做意味着两个常量(提前15天和21天)在运行时计算一次,然后没有使用其他函数,而如果你使用类似的东西:
DATEDIFF([day], Contract.EndDate, GETDATE()) < 20
您必须在每一行上执行DATEDIFF
函数,这意味着Contract.EndDate
上存在的任何索引都不能使用(谓词不是sargable)。即使没有索引存在,尽管开销很小,DATEDIFF
函数仍然有一点点,所以为什么只要一次就能执行数百,数千甚至数百万次的函数。
这也主要是个人偏好,因为只要您了解BETWEEN
正在做什么,查询就可以正确编写,但我总是在使用日期时使用开放式范围(即DATE >= X AND DATE < Y
)。它更清晰(IMO)并且不太可能导致意外结果。 Aaron Bertrand写了一篇关于这个主题的非常好的文章 - What do BETWEEN and the devil have in common?
对于它的价值,您的查询的问题是您的两个条款都指定日期小于特定日期:
WHERE (DATEDIFF([day], Contract.EndDate, GETDATE()) < 20)
这将限制在&#34; EndDate&#34;将来不到20天,这是期望的行为,以及下一个条款
AND (Contract.EndDate < DATEADD([day], 15, GETDATE()))
将行限制为&#34; EndDate&#34;将来不到15天,这不是理想的行为,第二个谓词中的<
应为>
。
以今天为例,你基本上有一个陈述
的where子句WHERE Contract.EndDate < '2015-08-18'
AND Contract.EndDate < '2015-08-13'
所以你有正确的上限,但这也将返回过去的所有行。