我在SQL Server 2005中有一个表,它有三列:
id (int),
message (text),
timestamp (datetime)
时间戳和身份证上有一个索引。
我有兴趣做一个查询,检索给定日期的所有消息,例如'12 / 20/2008'。但是我知道只是在timestamp = '12 / 20/2008'的地方做的不会给我正确的结果,因为该字段是一个日期时间字段。
有人建议使用DATEPART功能并将时间戳中的年,月和日拉出来并验证它们分别等于2008年,12年和20年。看起来这不会使用我在时间戳上的索引,并最终会进行全表扫描。
那么构建查询的最佳方法是什么,以便我利用我创建的索引?
答案 0 :(得分:2)
根据我的经验,使用两个日期时间变量总是无误的。决议问题似乎不太可能。然而,要记住的重要事实是范围(任何类型)包括两个端点。因此,您无法在两个日期使用BETWEEN进行测试,因为它将包括两者。而是使用像
这样的东西datefield> = @startdate AND datefield< @EndDate
C'mon伙计们 - 这方面的文件不是 很难找到。 :d
答案 1 :(得分:1)
-- avoid re-calculating @MyDate +1 for every row
DECLARE @NextDay DateTime
Set @NextDay = @MyDate + 1
SELECT
-- ...
WHERE [timestamp] >= @MyDate AND [timestamp] < @NextDay
答案 2 :(得分:0)
BETWEEN声明可以帮助您。
SELECT *
FROM MyTable
WHERE TimeStamp BETWEEN @Start AND @End;
开始将需要像你想要消息的那一天上午12:01那样,并且结束将在同一天结束时的晚上11:59。
答案 3 :(得分:0)
BETWEEN不执行&gt; =,&lt;。它的确是&gt; =,&lt; =,这个代码证明了这一点:
declare @low datetime
declare @high datetime
set @low = getdate()
set @high = @low+1
select case when @low between @low and @high then 1 else 0 end,
case when @high between @low and @high then 1 else 0 end
结果为1,1,表明=应用于两个边界。
答案 4 :(得分:0)
假设@Date是您想要所有消息的任何日期时间的日期时间值,请使用此
Where [timestamp] >= DateAdd(day, DateDiff(day, 0, @Date), 0)
And [timestamp] < DateAdd(day, DateDiff(day, 0, @Date), 1)
这比使用CAST快得多,更不用说在日期时间使用CAST时,如果将中午之后的日期时间值转换为整数,
Declare @MyDate as Datetime
Set @MyDate = '12/25/2008 12:01:00'
Declare @IntVal Integer
Set @IntVal = Cast(@MyDate as Integer)
Select Cast(@IntVal as DateTime)
它将向上舍入到表示NEXT日期的整数。上面的脚本将输出12/26/2008