当所有日期范围同时重叠时,获取所有重叠的日期范围

2024-04-12

我为此苦苦挣扎了几天......尝试编写一个 SQL 查询来获取所有单位同时重叠时的所有日期范围。最好以图形方式查看。

Here is the simplified table with the image for reference:

UnitId  Start       End
======  ==========  ==========
1       05/01/2018  09/01/2018
1       10/01/2018  13/01/2018
2       04/01/2018  15/01/2018
2       19/01/2018  23/01/2018
3       06/01/2018  12/01/2018
3       14/01/2018  22/01/2018

预期结果:

Start       End
======      ========== 
06/01/2018  09/01/2018
10/01/2018  12/01/2018

我目前拥有的:

DECLARE @sourceTable TABLE (UnitId int, StartDate datetime, EndDate datetime);
INSERT INTO @sourceTable VALUES
 (1, '2018-01-05', '2018-01-09')
,(1, '2018-01-10', '2018-01-13')
,(2, '2018-01-04', '2018-01-15')
,(2, '2018-01-19', '2018-01-23')
,(3, '2018-01-06', '2018-01-12')
,(3, '2018-01-14', '2018-01-22');

SELECT DISTINCT
 (SELECT max(v) FROM (values(A.StartDate), (B.StartDate)) as value(v)) StartDate
,(SELECT min(v) FROM (values(A.EndDate), (B.EndDate)) as value(v)) EndDate
FROM @sourceTable A 
JOIN @sourceTable B 
ON A.startDate <= B.endDate AND A.endDate >= B.startDate AND A.UnitId != B.UnitId

我相信这是“计算重叠间隔的数量”问题(这张图片应该有帮助 https://i.stack.imgur.com/a8xRs.png)。这是一种解决方案:

DECLARE @t TABLE (UnitId INT, [Start] DATE, [End] DATE);
INSERT INTO @t VALUES
(1, '2018-01-05', '2018-01-09'),
(1, '2018-01-10', '2018-01-13'),
(2, '2018-01-04', '2018-01-15'),
(2, '2018-01-19', '2018-01-23'),
(3, '2018-01-06', '2018-01-12'),
(3, '2018-01-14', '2018-01-22');

WITH cte1(date, val) AS (
    SELECT [Start], 1 FROM @t AS t
    UNION ALL
    SELECT [End], 0 FROM @t AS t
    UNION ALL
    SELECT DATEADD(DAY, 1, [End]), -1 FROM @t AS t
), cte2 AS (
    SELECT date, SUM(val) OVER (ORDER BY date, val) AS usage
    FROM cte1
)
SELECT date, MAX(usage) AS usage
FROM cte2
GROUP BY date

它将为您提供使用计数(可能)发生变化的所有日期的列表:

date          usage
2018-01-04    1
2018-01-05    2
2018-01-06    3
2018-01-09    3
2018-01-10    3
2018-01-12    3
2018-01-13    2
2018-01-14    2
2018-01-15    2
2018-01-16    1
2018-01-19    2
2018-01-22    2
2018-01-23    1
2018-01-24    0

通过这种方法,您不需要日历表或 rCTE 来构建缺失的日期。将以上转换为范围(2018-01-05 ... 2018-01-15, 2018-01-19 ... 2018-01-22等)并不是很困难。

DECLARE @t TABLE (UnitId INT, [Start] DATE, [End] DATE);
INSERT INTO @t VALUES
(1, '2018-01-05', '2018-01-09'),
(1, '2018-01-10', '2018-01-13'),
(2, '2018-01-04', '2018-01-15'),
(2, '2018-01-19', '2018-01-23'),
(3, '2018-01-06', '2018-01-12'),
(3, '2018-01-14', '2018-01-22');

WITH cte1(date, val) AS (
    SELECT [Start], 1 FROM @t AS t                 -- starting date increments counter
    UNION ALL                                      
    SELECT [End], 0 FROM @t AS t                   -- we need all edges in the result
    UNION ALL                                      
    SELECT DATEADD(DAY, 1, [End]), -1 FROM @t AS t -- end date + 1 decrements counter
), cte2 AS (
    SELECT date, SUM(val) OVER (ORDER BY date, val) AS usage -- running sum for counter
    FROM cte1
), cte3 AS (
    SELECT date, MAX(usage) AS usage -- group multiple events on same date together
    FROM cte2
    GROUP BY date
), cte4 AS (
    SELECT date, usage, CASE
        WHEN usage > 1 AND LAG(usage) OVER (ORDER BY date) > 1 THEN 0
        WHEN usage < 2 AND LAG(usage) OVER (ORDER BY date) < 2 THEN 0
        ELSE 1
    END AS chg -- start new group if prev and curr usage are on opposite side of 1
    FROM cte3
), cte5 AS (
    SELECT date, usage, SUM(chg) OVER (ORDER BY date) AS grp -- number groups for each change
    FROM cte4
)
SELECT MIN(date) date1, MAX(date) date2
FROM cte5
GROUP BY grp
HAVING MIN(usage) > 1

Result:

date1         date2
2018-01-05    2018-01-15
2018-01-19    2018-01-22
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当所有日期范围同时重叠时,获取所有重叠的日期范围 的相关文章

随机推荐

  • 自动添加或删除 Woocommerce 购物车中的免费产品

    我正在尝试创建代码 一旦客户达到购物车中的特定价格点 该代码就会自动将商品添加到客户的购物车中 如果他们只订购虚拟产品 我试图排除这种情况的发生 因为 免费礼物 仅适用于正在发货的产品 我使用的代码是以正确的金额添加免费礼物 但并不排除任何
  • 如何以 4/6/7 角度传递表单提交上的所有选中复选框值

    我想在组件中获取表单的所有已检查项目而不使用change or click 功能 因为它无法获取已检查的项目 这是我在 TS 中的数组 PartyRoles Id 1 Name Vendor Checked true Id 2 Name C
  • VSCode 中的 Flutter 初始化

    我一直在使用 VS Code 开发一个 flutter 项目 当我今天打开我的项目时 有一条通知显示 正在初始化 flutter 这可能需要几分钟 然后就被击中了 此外 flutter run 和 flutter doctor 等所有命令都
  • 将 WKNSURLRequest 崩溃为?其他类型

    当我尝试强制转换 WKNSURLRequest 以及其他类 全部来自 WebKit 框架 时 我遇到了严重崩溃 例如在游乐场 import UIKit import WebKit final class Sigh NSObject NSCl
  • bash set -e and i=0;让i++不同意

    仅当变量的先前值为零时 以下带有调试选项 set e v 的脚本才会在增量运算符处失败 bin bash set e v i 1 let i echo I am still here i 0 let i echo I am still he
  • 在 Flask 中使用 root_path 参数

    我尝试遵循一个教程 该教程旨在演示如何更改静态和模板文件夹在根目录中的位置 但是我无法让这个例子工作 应用程序运行正常 但在查找样式表 GET static style css HTTP 1 1 404 时返回 404 因此 它似乎可以找到
  • 如何从字符串形式的发送者向模拟器发送短信

    我经常在手机中收到短信 其中发送者中包含一些字符串而不是数字 例如公司名称 我想测试一些对这些短信做出反应的应用程序 但是如何将这样的短信发送到模拟器 如果我运行模拟器并执行以下操作 远程登录本地主机 5554 短信发送 MyBank 这是
  • 如何在 Lattice 包中将标签添加到 Levelplot 的顶部 X 轴

    所以我正在使用类似于此的 levelplot 制作类似相关矩阵的图 取自 将相关矩阵绘制成图表 https stackoverflow com questions 5453336 plot correlation matrix into a
  • 如何使带有前导零的不连续字符数字序列连续?

    我有这个字符向量 dput t line c 0304 0305 0306 0308 0311 0313 0314 0316 0318 0321 0322 0323 0324 0326 0327 0330 0333 0337 0338 03
  • 从服务器序列故障转移加载 .js?

    让我们想象一个网页需要加载一个 javascript 文件 即my js 是否可以组织以下故障转移加载顺序 如果服务器 A 已启动 则加载my js来自服务器A 否则 如果服务器 B 已启动 则加载my js来自服务器 B 否则 如果服务器
  • 使用maven仓库作为本地ivy缓存

    是否有可能使用本地 Maven 存储库 m2 作为本地 Ivy 缓存 ivy 他们有不同的布局 有时我使用 Maven 有时我使用 SBT 它在下面使用 Ivy 所以我在 Maven 和 Ivy 中都有相同库的 2 个副本 我想使用相同的目
  • iPhone 上 UIView 和 UILabels 上的渐变[重复]

    这个问题在这里已经有答案了 可能的重复 在 iPhone 应用程序中手动绘制渐变 https stackoverflow com questions 227005 manually drawing a gradient in iphone
  • 如何在函数内使用 ls() 搜索环境?

    我想找到一组函数并保存它们 因为我想将它们以 Rdata 文件发送到远程服务器 并且我不想在服务器上安装新的包 尽管我使用下面的方法遇到错误 但更简单 更好的方法是值得欢迎的 MWE 这是两个虚拟函数 abcd fun 1 lt funct
  • @Column columnDefinition 使哪些属性变得多余?

    我经常指定我的 Column像这样的注释 Column columnDefinition character varying 100 not null length 100 nullable false 正如你所看到的 我指定length
  • MySQL - 如何根据输入的长/纬度选择经度和纬度以逗号分隔的行?

    好的 我的数据库表中有以下两列 其中包含以下长 纬度 longitude 2 2426305000000184 0 7077123000000256 latitude 53 4807593 51 5459269 到目前为止我有这个查询 fu
  • Rails/ActiveRecord has_many through:未保存对象的关联

    让我们使用这些类 class User lt ActiveRecord Base has many project participations has many projects through project participation
  • 跨两个命名域共享会话 cookie

    我有一个具有以下域的 net Web 应用程序 www domain com 子域名 com 文件 domain com 当用户登录到domain com或sub domain com时 我希望他们共享会话状态 即同时登录到两个域 这可以通
  • 为什么所有现有的 C++ 编译器都不支持继承构造函数?

    目前 G 和 VC 2010 都不支持继承构造函数 然而 我认为这是 C 0x 中最美丽的功能之一 我认为编译器应该很容易实现它 为什么编译器对此功能不感兴趣 假设我想通过继承 std string 来设计自己的字符串类 如下所示 clas
  • 从文本文件打印所有回文

    我看了这个问题 BASH 回文检查器 https stackoverflow com questions 26601234 bash palindrome checker 这就是该线程中问题答案所显示的内容 grep E a z 3 45
  • 当所有日期范围同时重叠时,获取所有重叠的日期范围

    我为此苦苦挣扎了几天 尝试编写一个 SQL 查询来获取所有单位同时重叠时的所有日期范围 最好以图形方式查看 Here is the simplified table with the image for reference UnitId S