sql - Sql 查询以获取重叠日期间隔的外部
问题描述
我一直在尝试弄清楚如何为以下情况正确编写查询时遇到一些问题。我有一个表(TableA),其中 StartDate 和 EndDarte 作为 Date 列,以及一个 Type 列,它只能具有值 A 或 B。现在,当 B 型区间与 A 型区间重叠时,B 型将优先,类型 A 间隔将成为类型 B 间隔之外的任何内容。
例如:假设我们在表中有以下两行:
ID Type StartDate EndDate
1. A. 21-JAN-2021. 21-SEP-2021
2. B. 23-APR-2021. 27-AUG-2021
预期的结果应该是:
ID Type StartDate EndDate
1. A. 21-JAN-2021. 22-APR-2021
3. A. 28-AUG-2021. 21-SEP-2021
2. B. 23-APR-2021. 27-AUG-2021
这是一个简单的例子,似乎可以很好地使用联合,但是当我在一个更大的 TypeA 间隔中有多个 B 型间隔时,我不知道如何将它们分开。
在这张图片中,我们有 A 类第一个区间:AB和两个 B 类区间重叠GH和IJ 所以结果应该是:
|ID.| Type| StartDate.| EndDate|
|---|-----|--------------|----------|
|1. | A.| A. | G. |
|2. | B.| G. | H |
|3. | A.| H+1 | I-1. |
|4. | B.| I | J. |
有谁知道如何解决这个问题?谢谢
解决方案
查找“A”区间与“B”区间之间的间隙的交集
select t.*
from (
select *, lead(StartDate) over(order by StartDate) nxt
from tbl
where type='B') tb
outer apply (
select tb.ID, tb.Type, tb.StartDate, tb.EndDate
union all
select ta.ID, ta.Type,
case when ta.StartDate > tb.EndDate then ta.StartDate else tb.EndDate + 1 end,
case when ta.EndDate > tb.nxt then tb.nxt - 1 else ta.EndDate end
from tbl ta
where ta.type='A' and ta.StartDate < coalesce (tb.nxt, ta.StartDate + 1) and tb.EndDate < ta.EndDate
) t;
或者,您可以使用 JOIN 找到上述交叉点,并使用 UNION 添加 B 间隔。还添加了第一个 A 在第一个 B 之前开始的情况。
select *
from tbl
where type='B'
UNION ALL
select ta.ID, ta.Type,
case when ta.StartDate > coalesce(tb.EndDate, ta.StartDate -1) then ta.StartDate else tb.EndDate + 1 end StartDate,
case when ta.EndDate > tb.nxt then tb.nxt - 1 else ta.EndDate end EndDate
from (
-- before first B
select 0 id, null Enddate, min(startdate) nxt
from tbl
where type='B'
union all
select id, Enddate, lead(StartDate) over(order by StartDate) nxt
from tbl
where type='B') tb
join tbl ta
on ta.type='A' and ta.StartDate < coalesce (tb.nxt, ta.StartDate + 1) and coalesce(tb.EndDate, ta.EndDate - 1) < ta.EndDate
order by StartDate
推荐阅读
- python - 你如何在 matplotlib 的同一张图上有多个图
- java - 如何在spring boot中将实体保存在与数据库的关系中
- r - 是否可以将 count 与匹配表达式的函数一起使用?
- cocoapods - 如何在 CocoaPods post_install 挂钩中删除方案
- android - 在 Android 上使用 Firestore 的缓存策略
- c++ - 使用哪种方式来同步 vkQueueSubmit()?
- elasticsearch - 如何将日志与 APM 关联起来?
- zip - 如何将现有文件复制到 Julia 中的 zip 文件夹中
- php - Coinbase Pro - IP 与 IP 白名单不匹配问题,但 IP 已列入白名单
- flutter - 堆栈内的 IntrinsicHeight