检测同一个表中的重叠日期范围

Nae*_*raz 36 sql

我有一张包含以下数据的表格

PKey  Start       End         Type
====  =====       ===         ====
01    01/01/2010  14/01/2010  S
02    15/01/2010  31/01/2010  S
03    05/01/2010  06/01/2010  A
Run Code Online (Sandbox Code Playgroud)

并希望得到以下结果

PKey  Start       End         Type
====  =====       ===         ====
01    01/01/2010  14/01/2010  S
03    05/01/2010  06/01/2010  A
Run Code Online (Sandbox Code Playgroud)

关于从哪里开始的任何想法?我所做的很多阅读建议我需要创建条目,并且每天都要加入匹配日,这是唯一的方法吗?

SWe*_*eko 36

如果您已经有每天应该有效的条目,但如果不是,那么开销很大,如果经常使用该查询,则会影响性能.

如果数据采用这种格式,您可以使用简单的日期算法检测重叠,因为重叠只是在给定间隔之后开始的一个间隔,但在给定完成之前,类似于

select dr1.* from date_ranges dr1
inner join date_ranges dr2
on dr2.start > dr1.start -- start after dr1 is started
  and dr2.start < dr1.end -- start before dr1 is finished
Run Code Online (Sandbox Code Playgroud)

如果您需要对完全在另一个间隔内的间隔进行特殊处理,或者您需要合并间隔,即

PKey  Start       End         Type
====  =====       ===         ====
01    01/01/2010  20/01/2010  S
02    15/01/2010  31/01/2010  S
Run Code Online (Sandbox Code Playgroud)

生产

Start       End         Type
=====       ===         ====
01/01/2010  31/01/2010  S
Run Code Online (Sandbox Code Playgroud)

你需要更复杂的计算.

根据我对这类问题的经验,一旦你掌握了如何进行计算,就很容易将其转移到SQL中:)

  • 仅供参考,这个 sql 有点不完整。它确实检测到开始日期重叠,但不检测结束日期重叠(即结束日期位于另一个日期范围的中间)。您将需要另一个子句对...“或 dr2.end &gt; dr1.start 和 dr2end &lt; dr1.end”。在这里注意你的 ands,因为如果有任何其他标准(例如“S”与“A”),你可能需要一些括号 (4认同)

bob*_*et1 5

当我需要比较SQL中两个时间跨度的重叠时,可以想到以下四种情况:

  1. Span1开始在Span2开始和Span2结束之间
  2. Span1终点在Span2起点和Span2终点之间
  3. Span1的起点和终点都在Span2的起点和Span2的终点之间
  4. Span2的开始和结束都在Span1的开始和Span1的结束之间

这是我为捕获这些方案而创建的OR语句(在我的情况下为Oracle SQL):

and (
    s1.start between s2.start and s2.end
    OR
    s1.end between s2.start and s2.end
    OR
    s2.start between s1.start and s1.end
)
Run Code Online (Sandbox Code Playgroud)