我有一个事件表,用于指定包含start_date
和end_date
字段的日期范围。我有另一个在代码中指定的日期范围,它将当前周定义为'week_start'和'week_end'。
我想查询本周的所有活动。案件似乎是:
我正在尝试提出一个可以处理所有这些案例的查询。到目前为止,我只能得到处理周重叠的案例,或完全内部的事件;基本上,记录太多,或根本没有记录。
答案 0 :(得分:21)
(event.start BETWEEN week.start AND week.end)
OR
(week.start BETWEEN event.start AND event.end)
简单来说,要么在活动期间开始一周,要么在一周内开始活动。
我们来检查一下:
活动在一周内开始和结束
活动在一周内开始。
活动在一周之前开始,但在一周内结束
活动期间的一周开始。
活动在一周内开始,但在一周之后结束
活动在一周内开始。
活动在一周之前开始,也在一周之后结束
活动期间的一周开始。
请注意,上面表达式中的BETWEEN
仅用于简洁。
严格的表达式如下:
(event.start >= week.start AND event.start < week.end)
OR
(week.start >= event.start AND week.start < event.end)
,前提是week.end
是week.start + INTERVAL 7 DAY
。
予。即如果您在Sun, 0:00:00
周开始,那么它应该在next Sun, 0:00:00
上结束(不在Sat, 0:00:00
上)
此表达式看起来比常用的表达式更复杂:
event.start < week.end AND event.end > week.start
,但前者效率更高,索引友好。
请参阅我的博客中的这些文章,了解性能比较:
答案 1 :(得分:3)
你可以写下这样的条件:
start_date <= week_end AND end_date >= week_start
编辑:这假定start_date&lt; = end_date和week_start&lt; = week_end(正确排序),并且由于不使用OR(在某些数据库上可能会产生性能问题)而在大多数数据库实现上为您提供最佳性能
Edit2:此解决方案还解决了在间隔之前开始并在间隔之后结束的事件问题。
答案 2 :(得分:2)
+1为pop Catalin,但是我没有投票权。
您想要的限制条件只是表达Allen的“OVERLAPS”操作符的标准方式。
其他SQL警告:如果end_date可以为空,请务必将这些列中的空值视为“时间结束”。
附加功能警告:务必调整'&lt; ='与'&lt;'的用法记录的时间段是否包括结束日期。
答案 3 :(得分:0)
按顺序......
where start_date >= week_start and end_date <= week_end
where start_date <= week_start and end_date >= week_start and end_date <= week_end
where start_date >= week_start and start_date <= week_end and end_date > week_end
where start_date < week_start and end_date > week_end
答案 4 :(得分:0)
(end2&gt; = start1)&amp;&amp; (start2&lt; = end1)我认为对于任何相交的日期范围都会返回true。
我找到了有关此here的讨论,我发现它很有用。