Sql server 2008 TSQL在Where子句中使用时间

Sql server 2008 TSQL在Where子句中使用时间,sql-server-2008,tsql,Sql Server 2008,Tsql,我有一个存储在表中的温度测量值,每个测量值都有实际日期/时间,但从逻辑上讲,测量日从中午到中午,而不是午夜。 例如,在2011年9月18日09:00:00完成的测量将属于2011年9月18日测量日,但 2011年9月18日13:00:00完成的测量已属于2011年9月19日测量日 现在我想做一些统计查询,比如每个测量日09-11之间的平均温度,这是通过以下方式完成的: -- Select the AVG temp between 09-11 select MeasureDate, AVG

我有一个存储在表中的温度测量值,每个测量值都有实际日期/时间,但从逻辑上讲,测量日从中午到中午,而不是午夜。 例如,在2011年9月18日09:00:00完成的测量将属于2011年9月18日测量日,但 2011年9月18日13:00:00完成的测量已属于2011年9月19日测量日

现在我想做一些统计查询,比如每个测量日09-11之间的平均温度,这是通过以下方式完成的:

-- Select the AVG temp between 09-11    
select MeasureDate, AVG(Temp) from @d
where Time between '09:00:00' and '11:00:00'
Group by MeasureDate
但是如果我想要23:00-01:00之间的平均温度,我必须在不在此工作之间使用不同的查询时间:

-- Select the AVG temp between 23:00-01:00
select MeasureDate, AVG(Temp) from @d
where (Time>='23:00:00' or Time<='01:00:00')
Group by MeasureDate
有没有一种简单的方法可以让相同的查询支持这两种场景? 理想情况下,我希望有一个函数将@from/@to作为参数,并将结果作为表返回

下面是您可以运行的完整示例。 谢谢


简短而低效的回答:预先处理你的时间价值和你的比较价值;时间值滚动,因此您无需担心添加或删除天数:

SELECT MeasureDate, AVG(Temp) 
FROM @d
WHERE DateAdd(Hour, 12, [Time]) >= DateAdd(Hour, 12, Convert(Time, '09:00:00'))
    AND DateAdd(Hour, 12, [Time]) < DateAdd(Hour, 12, Convert(Time, '11:00:00'))
GROUP BY MeasureDate
这会给您提供一致的查询,尽管当然不是特别漂亮。您可以在其他地方预处理时间,无需在SQL中进行预处理

在性能方面,如果您已经或曾经需要时间/度量时间索引,则更正确的方法是存储预处理的度量时间并直接对其进行比较:

SELECT MeasureDate, AVG(Temp) 
FROM @d
WHERE MeasureTime >= DateAdd(Hour, 12, Convert(Time, '09:00:00'))
    AND MeasureTime < DateAdd(Hour, 12, Convert(Time, '11:00:00'))
GROUP BY MeasureDate
MeasureTime可以由客户机代码维护,或者作为索引计算列维护,或者由触发器维护——有很多种方法可以让您更加痛苦


请注意,在这些示例中,我使用了大于和小于版本,而不是中间版本,因为根据我的经验,在日期/时间上使用中间版本总是错误的。

这实际上根本不是对您问题的答案,但是为了避免报告中重复计算值,您可能不应该使用BETWEEN,而应该使用不等式:其中Time>='09:00:00'和Time<'11:00:00'Thx,出于某种原因,我得到了这个错误:Time和datetime的数据类型在大于或等于运算符中不兼容。这起作用了:DateAddHour,12,Time>=CONVERTTime,DateAddHour,12,'09:00:00'
SELECT MeasureDate, AVG(Temp) 
FROM @d
WHERE MeasureTime >= DateAdd(Hour, 12, Convert(Time, '09:00:00'))
    AND MeasureTime < DateAdd(Hour, 12, Convert(Time, '11:00:00'))
GROUP BY MeasureDate