2011-06-24 120 views
2

我试图让适合在时隙从一个表,其中从数据库中获得

  • 时隙开始在当前日期时间地板满小时
  • 时隙两端一定日期时隙在当前日期时间地板到整小时加2小时

这样一个DateTime是2011-06-24 09:21:40.020可能是之间:

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)) 

这应该会给我在当前活动时间段内的所有ComputerNames和Planned Dates。

回答

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

我想不出一个数学更清洁的方式做到这一点;但从代码嗅觉的角度来看,你可以编写一个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()));