2008-12-26 59 views
0

我有一个表如何查询SQL Server表。基于SQL Server 2005中有三个列的具体日期

我有兴趣做一个查询,检索给定日期的所有消息,比如'12/20/2008'。不过,我知道只是做timestamp = '12/20/2008'的地方不会给我正确的结果,因为这个字段是日期时间字段。

有人推荐使用DATEPART函数,并将年,月和日拉出时间戳,并验证它们分别等于2008,12和20。它看起来像不会使用我在时间戳上的索引,并且最终会进行全表扫描。

那么构建我的查询的最佳方式是什么,以便我利用我创建的索引?

回答

1
-- avoid re-calculating @MyDate +1 for every row 
DECLARE @NextDay DateTime 
Set @NextDay = @MyDate + 1 

SELECT 
    -- ... 
WHERE [timestamp] >= @MyDate AND [timestamp] < @NextDay 
+0

SQL服务器不够聪明,不能理解它只需要为语句计算@MyDate + 1一次吗? – erikkallen 2008-12-26 19:52:38

+0

也许吧。不过,我知道它不会为getdate()做这件事。当然这是一个函数调用,它有点不同。但是我对于在where子句中不需要的东西留下任何偏执。 – 2008-12-26 20:04:44

0

BETWEEN语句可以帮助您。

SELECT * 
FROM MyTable 
WHERE TimeStamp BETWEEN @Start AND @End; 

开始将需要像上午12:01你想要的消息的当天,和最终会像日下午11:59在同一天结束。

2

根据我的经验,两个日期时间变量的使用一直非常成功。决议的问题似乎不太可能。但是,要记住的重要事实是一个范围(任何类型)都包含两个端点。所以你不能在两个日期间使用BETWEEN进行测试,因为它包含了两个日期。而是使用类似

的DateField> = @startdate AND的DateField < @EndDate

The Manual.

来吧伙计 - 这个文件是不是很难找到。 :D

0

BETWEEN does not do> =,<。它确实> =,< =,因为这证明代码:

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,表明=被施加到两个边界。

0

假设@date是你想要的所有消息的任何一天的日期时间datetime值,使用此

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) 

将四舍五入到代表TNE第二天的日期整数。上面的脚本将输出12/26/2008

相关问题