检查 MySQL 中日期范围的重叠
该表用于存储会话(事件):
CREATE TABLE session (
id int(11) NOT NULL AUTO_INCREMENT
, start_date date
, end_date date
);
INSERT INTO session
(start_date, end_date)
VALUES
("2010-01-01", "2010-01-10")
, ("2010-01-20", "2010-01-30")
, ("2010-02-01", "2010-02-15")
;
我们不希望范围之间发生冲突。
假设我们需要插入一个从 2010-01-05 到 2010-01-25 的新会话。
我们想知道冲突的会话。
这是我的查询:
SELECT *
FROM session
WHERE "2010-01-05" BETWEEN start_date AND end_date
OR "2010-01-25" BETWEEN start_date AND end_date
OR "2010-01-05" >= start_date AND "2010-01-25" <= end_date
;
这是结果:
+----+------------+------------+
| id | start_date | end_date |
+----+------------+------------+
| 1 | 2010-01-01 | 2010-01-10 |
| 2 | 2010-01-20 | 2010-01-30 |
+----+------------+------------+
有更好的方法吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
我曾经编写过一个日历应用程序,有这样的查询。我想我使用了这样的东西:
更新这绝对应该有效 ((ns, ne, es, ee) = (new_start, new_end, Existing_start, Existing_end)):
这是一个 小提琴
I had such a query with a calendar application I once wrote. I think I used something like this:
UPDATE This should definitely work ((ns, ne, es, ee) = (new_start, new_end, existing_start, existing_end)):
Here is a fiddle
这3行sql子句涵盖了需要重叠的4种情况。
These 3 lines of sql clauses cover the 4 cases of overlapping required.
Lamy的答案很好,但是你可以再优化一下。
这将捕获范围重叠的所有四种情况,并排除不重叠的两种情况。
Lamy's answer is good, but you can optimize it a little more.
This will catch all four scenarios where the ranges overlap and exclude the two where they don't.
给定两个区间,如 (s1, e1) 和 (s2, e2),其中 s1
您可以这样计算重叠:
如果一个间隔在另一个间隔内,也将起作用。
Given two intervals like (s1, e1) and (s2, e2) with s1<e1 and s2<e2
You can calculate overlapping like this:
Will also work if one interval is within the other one.
我也遇到过类似的问题。我的问题是在一系列封锁日期之间停止预订。例如,5 月 2 日至 7 日期间的酒店预订将被阻止。我需要找到任何类型的重叠日期来检测并停止预订。我的解决方案类似于LordJavac。
如果不起作用请告诉我。
I had faced the similar problem. My problem was to stop booking between a range of blocked dates. For example booking is blocked for a property between 2nd may to 7th may. I needed to find any kind of overlapping date to detect and stop the booking. My solution is similar to LordJavac.
Let me know if it doesn't work.
即使数据库中的 to-date 可能为空,您也可以覆盖所有日期重叠的情况,如下所示:
这将返回与新的开始/结束日期重叠的所有记录。
You can cover all date overlapping cases even when to-date in database can possibly be null as follows:
This will return all records that overlaps with the new start/end dates in anyway.
从性能角度来看,Mackraken 的上述答案更好,因为它不需要多个 OR 来评估两个日期是否重叠。很好的解决方案!
然而我发现在 MySQL 中你需要使用 DATEDIFF 而不是减号运算符 -
Mackraken's answer above is better from a performance perspective as it doesn't require several OR's in order to evaluate if two dates overlap. Nice solution!
However I found that in MySQL you need to use DATEDIFF instead of the minus operator -
最近我正在努力执行日期操作。以下 SQL 查询解决了过滤具有与日期相关的多个条件的行的问题:
PS:这帮助我找到了具有重叠日期范围的条目,但可能不是一个好方法,因为它可能会消耗内存。
Recently I was struggling to perform operations with date. The following SQL query solved the issue to filter rows with multiple criteria related to date:
PS: This helped me find the entries with overlapping date ranges however may not be a good approach as it may be memory consuming.