请帮我解决问题。因此,我有一个名为"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
假设 @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))
我真的从不使用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';
这可能不完全正确,但它可以帮助您朝正确的方向看。
我想@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 和截断日期时间值的技巧。 要理解这个技巧,请阅读以下问题和答案:在SQL服务器中放置日期
下面是此查询功能的概述:
创建一个规范化表,每个时间跨度仅超过一天
- 选择同一天出现的所有行。
然后对于跨越两天的每个条目加入
- 选择开始时间和第二天前一秒作为所有跨度的结束时间。
和
- 选择end_time日期的凌晨 12 点作为开始时间和end_time。
最后,使用此规范化表上的小时指示器执行选择。
如果范围超过一天,则需要使用递归 CTE 来获取相同的规范化表。