0

我意识到这是一个相对基本的问题,但是日期时间总是把我搞砸,我想确保我做得正确(这个审计将被提升为老板)。使用 sql server 2008 r2。下面是我想要的一些 sudo 代码

我应该提到 transactionDate 目前是一个日期时间。这会改变事情吗?

DELCARE 
    @today datetime,
    @tomorrow datetime

SET @today = --CODE TO GET THE DATE FOR TODAY
SET @tomorrow = --CODE TO GET THE DATE FOR TOMORROW

SELECT *
FROM table
WHERE custID = '788'
    AND status = 'Cancelled'
    AND transactionDate --IS ONLY TODAY AND NOT TOMORROW OR ANY DAY AFTER
4

4 回答 4

7

如果transactionDateDATETIME,那么:

AND CONVERT(DATE, TransactionDate) = CONVERT(DATE, CURRENT_TIMESTAMP);

如果transactionDateDATE,那么:

AND transactionDate = CONVERT(DATE, CURRENT_TIMESTAMP);

这两个仍将使用索引 on transactionDate,但这是一种特殊情况。通常第一种形式会破坏 sargability。

于 2013-03-22T20:35:58.740 回答
2

如果您使用日期,那么您应该使用date数据类型。这是您的查询的一个版本:

SELECT *
FROM table
WHERE custID = '788'
    AND status = 'Cancelled'
    AND cast(transactionDate as date) = cast(getdate() as date)

你也可以这样写:

select *
from table
where custId = '788' and status = 'Cancelled' and
      TransactionDate >= cast(getdate() as date) and
      TransactionDate < cast(getdate() + 1 as date)

我认为演员表阻止了索引被使用,但亚伦在评论中启发了我。 是对 SQL Server 中 sarability 的更广泛解释。

于 2013-03-22T20:36:42.830 回答
0

正如其他人发布的那样,有几种方法可以做到这一点。

最好的方法是简单地设置

where transactionDate = @toDay

如果 transactionDate 仅包含 DATE 部分(没有小时或分钟,所以在午夜),然后 @toDay 相同,仅用于 GETDATE() 或类似的,则此方法将起作用。

正如 ljh 所写,您也可以在当天执行 DATEDIFF,但这将是广泛的,因为它将在每一行上执行 DATEDIFF - 效率不高。

但是,您可以在日期之间检查,所以像这样。

WHERE transactionDate >= '2013-03-22' and transactionDate < '2013-03-23'
--Substitute the chars for variables

这将为您提供在午夜和下一个午夜之间发生 transactionDate 的所有行。

编辑:我刚刚看到 Gordon 回答了同样的问题,并包括了关于索引可用的部分,我忘记添加了。

编辑:正如亚伦指出的那样,两者之间不是一件好事。自从我真正编写任何非临时 sql 以来已经有一段时间了,所以我倾向于忘记这样的东西:(

于 2013-03-22T20:51:34.103 回答
0

这可能会对您有所帮助,只需将 GETDATE() 替换为您的输入 DATE


SELECT *
FROM table
WHERE custID = '788'
    AND status = 'Cancelled'
    AND DATEDIFF(DD,GETDATE(),transactionDate)=0
于 2013-03-22T20:42:56.853 回答