时间范围 - Sql

时间:2011-05-09 18:06:18

标签: sql sql-server datetime range

请帮我解决我的问题。所以,我有一个名为'RATES'的表,其中包含以下列:

id (int) 
rate (money) 
start_time (datetime) 
end_time(datetime)

示例数据:

1 150 8:00am 6:00pm 
2 200 6:00pm 4:00am
3 250 8:00am 4:00am (the next day)

我要做的是选择给定时间下降的所有id。

例如给定时间:晚上9:00,输出应为2,3

问题是我在第二天早上8点到凌晨4点之间得到了这个时间范围,我不知道该怎么办。请帮忙!提前谢谢:D

3 个答案:

答案 0 :(得分:3)

假设@Andriy M是正确的:

  • 数据永远不会超过24小时
  • 如果end_time< = start_time,那么end_time属于第二天
那么你要找的是:

Declare @GivenTime DateTime
Set @GivenTime = '9:00 PM'
Select ID
  From Rates
 Where (Start_Time<End_Time And Start_Time<=@GivenTime And End_Time>=@GivenTime)
    Or (Start_Time=End_Time And Start_Time=@GivenTime)
    Or (Start_Time>End_Time And (Start_Time>=@GivenTime Or End_Time<=@GivenTime))

答案 1 :(得分:0)

我真的不使用MS SQL,但也许这会有所帮助。

我打算建议这样的事情,但是按照你设置数据的方式,这会失败。

SELECT id FROM RATES WHERE datepart(hh, start_time) <= 9 AND datepart(hh, end_time) >= 9;

如果您希望获得正确的数据,您可以使用实际日期进行搜索。

SELECT id FROM RATES WHERE start_time <= '2011-1-1 9:00' AND end_time >= '2011-1-1 9:00';

这可能不完全正确,但它可能有助于您朝着正确的方向前进。

答案 2 :(得分:0)

我猜@gbn不会帮助你。我会尽力填写。

给定 - 一个名为timedata的表,其范围最多只能超过一天

WITH normalized AS
(
   SELECT * 
   FROM timedata
   WHERE datepart(day,start_time) = datepart(day,endtime)
   UNION ALL
   SELECT id, rate, start_time, dateadd(second,dateadd(day,datediff(day,0,end_time),0),-1) as end_time 
   FROM timedata
   WHERE not (datepart(day,start_time) = datepart(day,endtime))
   UNION ALL
   SELECT id, rate,dateadd(day,datediff(day,0,end_time),0) as start_time, end_time
   FROM timedata
   WHERE not (datepart(day,start_time) = datepart(day,endtime))
)
SELECT * 
FROM normalized
WHERE datepart(hour,start_time) < @inhour
  AND datepart(hour,end_time) > @inhour

这使用CTE和截断日期时间值的技巧。要理解这个技巧,请阅读以下问题并回答:Floor a date in SQL server

以下是此查询的作用概述:

创建一个规范化的表格,每个时间跨度仅超过一天

  • 选择同一天发生的所有行。

然后对于每天加入

两天的条目
  • 选择开始时间和第二天之前的一秒作为所有跨度的结束时间。

  • 选择end_time date的12am作为starttime和end_time。

最后,使用此规范化表格上的小时指示符执行​​选择。

如果您的范围超过一天,则需要使用递归CTE来获取相同的规范化表格。