从数据库中获取时间段

时间:2011-06-24 07:22:39

标签: sql sql-server tsql sql-server-2008 query-optimization

我正在尝试从表格

获取适合时区的某些日期
  • 时间段以当前日期时间开始 开始至整个小时
  • 时间段结束,当前日期时间已落实至完整小时加上2小时

所以2011-06-24 09:21:40.020的DateTime可以介于:

之间
2011-06-24 09:00:00.000 AND 2011-06-24 11:00:00.000

目前我已经有了这个,但我认为嵌套的DATEADD是多余的。有更清洁的方法吗?

SELECT     dbo.Computer.ComputerName, dbo.Planned.DatePlanned
FROM       dbo.Computer INNER JOIN
           dbo.Planned ON dbo.Computer.ComputerID = dbo.Planned.ComputerID
WHERE      dbo.Planned.DatePlanned 
BETWEEN
(SELECT    DATEADD(Hour, DATEDIFF(Hour, 0, GETDATE()), 0)) 
AND
(SELECT    DATEADD(Hour, DATEDIFF(Hour, 0, DATEADD(Hour, 2, GETDATE())), 0))

这应该给我当前活动时间段中的所有计算机名称和计划日期。

2 个答案:

答案 0 :(得分:1)

我认为定义这两个变量更清晰:

DECLARE @Start DATETIME = DATEADD(Hour, DATEDIFF(Hour, 0, GETDATE()), 0)
DECLARE @End DATETIME = DATEADD(Hour, 2, @Start)

SELECT dbo.Computer.ComputerName, dbo.Planned.DatePlanned
FROM dbo.Computer 
    INNER JOIN dbo.Planned ON 
        dbo.Computer.ComputerID = dbo.Planned.ComputerID
WHERE dbo.Planned.DatePlanned 
BETWEEN @Start AND @End

答案 1 :(得分:1)

我想不出以数学上更干净的方式去做;但就代码味道而言,您可以编写一个UDF(自SQL 2000起支持)。您可以从UDF获得一点额外的性能并在计算列中使用它(前提是它在两种情况下都是绑定模式)。

CREATE FUNCTION [dbo].[DateTimeHourFloor]
(
    @DateTime DATETIME
)
RETURNS DATETIME
WITH SCHEMABINDING -- A little more perf.
AS BEGIN
    RETURN DATEADD(Hour, DATEDIFF(Hour, 0, @DateTime), 0);
END;

然后你可以这样使用它:

SELECT     dbo.Computer.ComputerName, dbo.Planned.DatePlanned
FROM       dbo.Computer INNER JOIN
           dbo.Planned ON dbo.Computer.ComputerID = dbo.Planned.ComputerID
WHERE      dbo.Planned.DatePlanned 
BETWEEN    [dbo].[DateTimeHourFloor](GETDATE())
    AND    [dbo].[DateTimeHourFloor](DATEADD(Hour, 2, GETDATE()));