提问人:imvain2 提问时间:8/18/2023 最后编辑:imvain2 更新时间:8/19/2023 访问量:45
mySQL Between Time Range - 开始时间可以大于结束时间
mySQL Between Time Range - Where start time can be greater than end time
问:
我尝试在 SO 中搜索这个问题,但找不到与 mySQL 相关的任何内容。
我有一个包含各种数据的表格,但对于这个问题,相关数据是星期几、开始时间和结束时间。
我正在尝试获取与一周中某一天匹配的记录,其中 now() 在匹配的时间范围内。但是,问题是开始时间可以大于结束时间,反之亦然,或者时间也可能只是 00:00:00。
表格的相关字段和示例数据:page_data
field_value | start_time | end_time
------------+------------+---------
Monday | 17:00:00 | 08:00:00
Tuesday | 17:00:00 | 08:00:00
Wednesday | 17:00:00 | 08:00:00
Thursday | 17:00:00 | 08:00:00
Friday | 17:00:00 | 08:00:00
Saturday | 00:00:00 | 00:00:00
Sunday | 00:00:00 | 00:00:00
几点说明:
- 00:00:00 - 00:00:00 基本上意味着全天跑步
- 如果开始时间大于结束时间,例如 17:00 - 8:00,则会 意思是从下午 5 点跑到第二天早上 8 点。
我试过了,但这并不涵盖start_time > end_time。now() between start_time and end_time
以下是我到目前为止所拥有的,但它在不应该返回的时候返回。
10:00:00 是一个测试时间,不应返回任何内容,但它确实返回。
为了测试,我硬编码了一个时间,而不是使用now()
如果我删除,那么start_time更大不会返回任何东西。or ('10:00:00' between end_time and start_time)
select * from page_data
where field_value = 'Friday'
and (
(start_time = '00:00:00' and end_time = '00:00:00') or
('10:00:00' between start_time and end_time) or
('10:00:00' between end_time and start_time)
)
我对可用于考虑以下注意事项的查询感到困惑:
- 开始时间>结束时间
- 结束时间>开始时间
- 结束时间和开始时间 = 00:00:00
谢谢
答:
在start_time > end_time的情况下,我猜你只想匹配test_time大于 start_time 或小于 end_time。这在逻辑上等同于end_time和start_time之间的test_time NOT。
如果此逻辑正确,则可能需要以下代码:
select * from page_data
where field_value = 'Friday'
and (
(start_time = '00:00:00' and end_time = '00:00:00') or
(start_time < end_time) and ('10:00:00' between start_time and end_time) or
(start_time > end_time) and NOT('10:00:00' between end_time and start_time)
)
评论
你喜欢这个吗?
SELECT ...
FROM easier_to_work_with
WHERE day_of_week = DAYNAME(CURRENT_DATE)
AND
CURRENT_TIME BETWEEN start_time AND end_time;
在我看来,将“通知窗口”周期指定为限制在一天内的时间间隔会更容易,将跨越一天以上的窗口表示为两个相邻的窗口。
然后,您只需根据窗口检查当前日期和当前时间即可。
您可以在不更改现有应用程序逻辑或现有表结构的情况下执行此操作:
CREATE VIEW easier_to_work_with AS
-- get same day windows
SELECT ..., field_value as day_of_week, start_time, end_time
FROM page_data
WHERE start_time < end_time
UNION
-- get all day windows, or partials crossing midnight
SELECT ..., field_value, start_time, '23:59:59'
FROM page_data
WHERE (start_time = '00:00:00' AND end_time = '00:00:00')
OR
end_time < start_time
UNION
-- get carryover windows from the previous day
SELECT ...,
CASE field_value
WHEN 'Monday' THEN 'Tuesday'
WHEN 'Tuesday' THEN 'Wednesday'
WHEN 'Wednesday' THEN 'Thursday'
WHEN 'Thursday' THEN 'Friday'
WHEN 'Friday' THEN 'Saturday'
WHEN 'Saturday' THEN 'Sunday'
WHEN 'Sunday' THEN 'Monday'
END, '00:00:00', end_time
FROM page_data
WHERE end_time < start_time;
评论
('Weds', '17:00', '08:00')