【问题标题】:How to determine if a date range occurs any time within another date range?如何确定一个日期范围是否出现在另一个日期范围内的任何时间?
【发布时间】:2009-04-08 16:14:03
【问题描述】:

我有一个事件表,它使用 start_dateend_date 字段指定日期范围。我在代码中指定了另一个日期范围,它将当前周定义为“week_start”和“week_end”。

我想查询本周的所有事件。这些案例似乎是:

  • 活动在一周内开始和结束
  • 活动在一周前开始,但在一周内结束
  • 活动在一周内开始,但在一周后结束
  • 活动在一周前开始并在一周后结束
  • 既不在一周内也不与一周重叠的事件将被忽略

我正在尝试提出一个可以处理所有这些情况的查询。到目前为止,我只能获得处理周重叠或完全内部事件的案例;本质上,记录太多,或者根本没有。

【问题讨论】:

标签: database datetime logic


【解决方案1】:
(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.endweek.start + INTERVAL 7 DAY

我。 e.如果你的一周开始于Sun, 0:00:00,那么它应该在next Sun, 0:00:00 结束(而不是Sat, 0:00:00

这个表达式看起来比常用的更复杂:

event.start < week.end AND event.end > week.start

,但前者效率更高,索引更友好。

有关性能比较,请参阅我的博客中的这些文章:

【讨论】:

  • 这里只是为了简洁。作为一项规则,周末应该是一个严格的更少。
  • 太糟糕了,这并不能解决在一周前开始并在一周后结束的事件的问题。
  • @Pop Catalin:真的吗?相关周不是在活动期间开始吗?
  • 您的答案是正确的,但我使用的是 Django,因此只能从左到右查询,可以这么说。所以现在我必须将 OR 之后的所有内容翻译成适合 Django 使用的“field__operator=value”表示法的东西。
  • -1 这既复杂又低效。最好的解决方案实际上是由 Pop Catalin 提出的 event.start week.start。
【解决方案2】:

你可以这样写你的条件:

start_date <= week_end AND end_date >= week_start

编辑:这假设 start_date

Edit2:这个解决方案还解决了事件在区间之前开始并在区间之后结束的问题。

【讨论】:

  • 区间比较比 between 更好的解决方案
【解决方案3】:

+1 for pop Catalin,可惜我没有投票权。

您想要的限制条件只是表示艾伦的“OVERLAPS”运算符的标准方式。

其他 SQL 警告:如果 end_date 可以为空,请务必将这些列中的空值视为“时间结束”。

附加功能警告:请务必调整“

【讨论】:

    【解决方案4】:

    按顺序...

    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
    

    【讨论】:

      【解决方案5】:

      (end2 >= start1) && (start2

      我发现了一个关于这个here 的讨论,我觉得很有用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-12-27
        • 1970-01-01
        • 2019-04-26
        • 2020-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多