SQL Server 2014 合并重叠的日期范围

2024-01-11

我在 SQL Server 2014 数据库中有一个包含 200.000 行的表,如下所示:

CREATE TABLE DateRanges
(
     Contract VARCHAR(8),
     Sector VARCHAR(8),
     StartDate DATE,
     EndDate DATE
);

INSERT INTO DateRanges (Contract, Sector, StartDate, Enddate)
   SELECT '111', '999', '01-01-2014', '03-31-2014'
   union
   SELECT '111', '999', '04-01-2014', '06-30-2014'
   union
   SELECT '111', '999', '07-01-2014', '09-30-2014'
   union
   SELECT '111', '999', '10-01-2014', '12-31-2014'
   union
   SELECT '111', '888', '08-01-2014', '08-31-2014'
   union
   SELECT '111', '777', '08-15-2014', '08-31-2014'
   union
   SELECT '222', '999', '01-01-2014', '03-31-2014'
   union
   SELECT '222', '999', '04-01-2014', '06-30-2014'
   union
   SELECT '222', '999', '07-01-2014', '09-30-2014'
   union
   SELECT '222', '999', '10-01-2014', '12-31-2014'
   union
   SELECT '222', '666', '11-01-2014', '11-30-2014'
   UNION
   SELECT '222', '555', '11-15-2014', '11-30-2014';

正如您所看到的,每个合同可能有多个重叠,我想要的是这样的结果

    Contract   Sector   StartDate     EndDate
    ---------------------------------------------
    111        999      01-01-2014    07-31-2014
    111        888      08-01-2014    08-14-2014
    111        777      08-15-2014    08-31-2014
    111        999      09-01-2014    12-31-2014

    222        999      01-01-2014    10-31-2014
    222        666      11-01-2014    11-14-2014
    222        555      11-15-2014    11-30-2014
    222        999      12-01-2014    12-31-2014

我不知道如何做到这一点,并且我在该网站上看到的示例完全不适合我的问题。


这个答案使用了一些不同的技术。第一个是递归cte /questions/tagged/recursive-cte创建一个包含每个相关的表cal_date然后得到cross apply具有独特的Contract值来获取这两个值的每个组合。第二个是窗口函数 /questions/tagged/window-functions例如lag https://learn.microsoft.com/en-us/sql/t-sql/functions/lag-transact-sql and row_number https://learn.microsoft.com/en-us/sql/t-sql/functions/row-number-transact-sql确定下面评论中详细说明的各种事情。最后,也许也是最重要的一点是,间隙和岛屿 /questions/tagged/gaps-and-islands来确定何时Contract/Sector组合结束,下一个组合开始。

Answer:

--determine range of dates 
declare @bgn_dt date = (select min(StartDate) from DateRanges)
    , @end_dt date = (select max(EndDate) from DateRanges)

--use a recursive CTE to create a record for each day / Contract
; with dates as
    (
        select @bgn_dt as cal_date
        union all
        select dateadd(d, 1, a.cal_date) as cal_date
        from dates as a
        where a.cal_date < @end_dt
    )
select d.cal_date
, c.Contract
into #contract_dates
from dates as d
cross apply (select distinct Contract from DateRanges) as c
option (maxrecursion 0)

--Final Select
select f.Contract
, f.Sector
, min(f.cal_date) as StartDate
, max(f.cal_date) as EndDate
from (
    --Use the sum-over to obtain the Island Numbers
    select dr.Contract
    , dr.Sector
    , dr.cal_date
    , sum(dr.IslandBegin) over (partition by dr.Contract order by dr.cal_date asc) as IslandNbr
    from (
        --Determine if the record is the start of a new Island
        select a.Contract
        , a.Sector
        , a.cal_date
        , case when lag(a.Sector, 1, NULL) over (partition by a.Contract order by a.cal_date asc) = a.Sector then 0 else 1 end as IslandBegin
        from (
            --Determine which Contract/Date combinations are valid, and rank the Sectors that are in effect
            select cd.cal_date
            , dr.Contract
            , dr.Sector
            , dr.EndDate
            , row_number() over (partition by dr.Contract, cd.cal_date order by dr.StartDate desc) as ConractSectorRnk
            from #contract_dates as cd
            left join DateRanges as dr on cd.Contract = dr.Contract
                                      and cd.cal_date between dr.StartDate and dr.EndDate
            ) as a
        where a.ConractSectorRnk = 1
        and a.Contract is not null
        ) as dr
    ) as f
group by f.Contract
, f.Sector
, f.IslandNbr
order by f.Contract asc
, min(f.cal_date) asc

Output:

+----------+--------+------------+------------+
| Contract | Sector | StartDate  |  EndDate   |
+----------+--------+------------+------------+
|      111 |    999 | 2014-01-01 | 2014-07-31 |
|      111 |    888 | 2014-08-01 | 2014-08-14 |
|      111 |    777 | 2014-08-15 | 2014-08-31 |
|      111 |    999 | 2014-09-01 | 2014-12-31 |
|      222 |    999 | 2014-01-01 | 2014-10-31 |
|      222 |    666 | 2014-11-01 | 2014-11-14 |
|      222 |    555 | 2014-11-15 | 2014-11-30 |
|      222 |    999 | 2014-12-01 | 2014-12-31 |
+----------+--------+------------+------------+
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SQL Server 2014 合并重叠的日期范围 的相关文章

  • 跳过行:将数据从 SSIS 导出到 Excel 文件

    我正在尝试使用 SSIS 将数据从 SQL Server 数据库导出到 Excel 文件中 我希望从第 6 行插入数据 第 5 行有标题 我可以映射标题名称Excel 目标编辑器 通过编写 SQL 命令到 SQL 表头 SELECT FRO
  • 重用 t-sql 游标的起始位置?

    我正在开发一个在临时表上使用游标的存储过程 我已经阅读了一些关于为什么不需要游标的内容 但在这种情况下我相信我仍然需要使用游标 在我的过程中 我需要遍历表的行两次 声明游标后 已经单步执行临时表并关闭游标 重新打开时游标的位置是否仍保留在表
  • ADO.NET SQLServer:如何防止关闭的连接持有S-DB锁?

    i Dispose http msdn microsoft com en us library system data sqlclient sqlconnection close aspx一个 SqlConnection 对象 但是当然它并
  • 如何使用 SQL 查询创建逗号分隔的列表?

    我有 3 个表 名为 应用程序 ID 名称 资源 id 名称 应用程序资源 id app id resource id 我想在 GUI 上显示所有资源名称的表格 在每一行的一个单元格中 我想列出该资源的所有应用程序 以逗号分隔 所以问题是
  • 如何将 SQL Server 中同一表中的一列插入到另一列中

    我需要将一列的数据插入到同一个表中的另一列中 谁能告诉我这个怎么写 Thanks UPDATE table SET col 2 col 1
  • 无法批量加载。操作系统错误代码 5(访问被拒绝。)

    由于某些奇怪的原因 我在执行批量插入时遇到问题 BULK INSERT customer stg FROM C Users Michael workspace pydb data andrew out txt WITH FIRSTROW 0
  • SQL Server默认字符编码

    默认情况下 Microsoft SQL Server 中数据库的字符编码集是什么 如何查看 SQL Server 中当前的字符编码 编码 In most cases SQL Server stores Unicode data i e th
  • 如何在审计触发器中使用system_user但仍使用连接池?

    我想做以下两件事 在我的数据库表上使用审计触发器来识别哪个用户更新了什么 使用连接池来提高性能 对于 1 我在数据库触发器中使用 system user 来识别进行更改的用户 但这阻止我执行需要通用连接字符串的 2 有没有一种方法可以让我充
  • 如果存在多个相同的 ID,则使用 where 子句

    我有下表 ID source Name Age 1 SQL John 18 2 SAP Mike 21 2 SQL Mike 20 3 SAP Jill 25 我希望每个ID都有一条记录 这背后的想法是 如果 ID 仅出现一次 无论来源如何
  • SQL Server 每年的第一个星期一

    如何使用 T SQL 查找 一年中的第一个星期一 这是 ngruson 发布的链接中的示例 http sqlbump blogspot nl 2010 01 first monday of year html http sqlbump bl
  • 在一个查询中对同一个表进行多个 COUNT SELECT

    对于某些人来说 这可能看起来很简单 但我就是无法理解 我一遍又一遍地从同一个表中进行多个 MS SQL SELECT 查询 SELECT count Page as tAEC FROM someTable WHERE Page LIKE A
  • SQL Server 端口 445 和 1433

    SQL Server 端口 445 和 1433 之间有什么区别以及每个端口的用途是什么 445不是SQL端口 是SMB端口 仅当您使用命名管道协议时 它才会参与 SQL Server 因为命名管道通过 SMB 进行传输 而这反过来又使用
  • 当两个表非常相似时,什么时候应该将它们合并?

    我有事件和照片 然后对两者进行评论 现在 我有两个评论表 一个用于与事件相关的评论 另一个用于照片评论 架构与此类似 CREATE TABLE EventComments CommentId int EventId int Comment
  • 使用 SQL 扩展事件捕获链接服务器查询

    我尝试了许多事件类型 但无法实现链接服务器的日志记录 我可以找出所有其他数据库的事件 但对于链接服务器却没有运气 有什么建议 您可以使用OLEDB DATA READ跟踪对链接服务器的查询的事件 如果此事件的结果比您想要的更详细 您可能需要
  • PostgreSQL 窗口函数:row_number() over(按 col2 分区 col 顺序)

    以下结果集源自具有一些连接和联合的 SQL 查询 SQL 查询已经对 Date 和 game 上的行进行了分组 我需要一列来描述按日期列分区的游戏的尝试次数 Username Game ID Date johndoe1 Game 1 100
  • Java 和 SQL Server 中的精度噩梦

    我一直在与 Java 和 SQL Server 中的精确噩梦作斗争 直到我不再知道了 就我个人而言 我理解这个问题及其根本原因 但向地球另一端的客户解释这一点是不可行的 至少对我来说 情况是这样的 我在 SQL Server 中有两列 Qt
  • INNER/RIGHT/LEFT JOIN 怎么会比 FULL JOIN 慢 14 倍?

    我有一个查询 使用 FULL JOIN 需要 2 5 秒 使用 INNER RIGHT 或 LEFT JOIN 需要 40 秒 这是查询 子查询 完成两次 本身只需要 1 3 秒 SELECT T1 time T1 Total T1 rn
  • Razor C# - 从数据库获取数据

    我正在使用 WebMatrix 我创建了一个数据库并放置了一个包含几行数据的表 我可以连接到它并获取数据WebGrid 但它只提供了一种使用表格输出数据的方法 这是我的 shows cshtml 代码 var db Database Ope
  • SSRS ReportViewer 与 XML 嵌入数据源相关的问题

    我有 C WPF 应用程序 我想在 ReportViewer 控件中显示 SSRS 报告 本地报告文件中嵌入了 XML 数据源 从 SQL Server Business Intelligence Development Studio 运行
  • 如何重置 SQL Server 中表的 IDENTITY 列? [复制]

    这个问题在这里已经有答案了 我怎样才能重置我的IDENTITY我已经填充的表中的列 我尝试过类似的方法 但它不起作用 WITH TBL AS SELECT ROW NUMBER OVER ORDER BY profile id AS RN

随机推荐

  • 如何使文本在节点中居中?

    我正在学习关于d3 js和力量体系 我有一个拦截器 因为我无法添加文本 并且它完全位于圆圈的中心 我曾尝试创建
  • 纯 WebGL 虚线

    我正在尝试使用纯 webgl 创建一条虚线 我知道已经有一个问题了 也许我很蠢 但我不知道如何让它发挥作用 我理解这个概念 但我不知道如何获取着色器中沿路径的距离 之前的答案有以下一行 varying float LengthSoFar l
  • 为什么结构体和可变结构体具有不同的默认相等运算符?

    我有以下代码 julia gt struct Point x y end julia gt Point 1 2 Point 1 2 true julia gt mutable struct Points x y end julia gt P
  • 如何获取谷歌地图标记上的双击事件[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 在我的应用程序中 我显示具有多个标记的谷歌地图 因为我有点击事件和获取信息窗口 但是我需要的是 当我双击标记时 应该显示包含有关该标记
  • 尝试连接到 .onion 站点时 Python 请求失败

    我正在尝试获取托管在 tor 网络中的网页 我正在使用以下代码 import requests def get tor session session requests session session proxies http socks5
  • CSS,自动调整div大小?

    我正在尝试用 css 设计一种布局 我有一个主容器 div 和两个内部容器 div upper 和 div lower 假设我想调整 div upper 和 div lower 的大小 它们会自动调整自身大小 并且两个 div 仍然适合主容
  • Azure Linux 应用服务:从 DevOps 管道部署后安装包

    我目前正在 Azure Devops 中设置 CI CD 管道 以在 Linux 托管应用程序服务 而不是 VM 上部署 NodeJS 应用程序 我的构建和部署都很顺利 但我需要确保在部署应用程序后在环境中安装一些软件包 问题是 无论如何a
  • 为什么人们使用 #ifdef 进行功能标志测试?

    People 推荐 ifdef条件编译大幅提高 https stackoverflow com q 21256252 103167 A 搜索 ifdef https stackoverflow com search q 23ifdef证实其
  • 以编程方式安装 Windows 服务

    如何在不使用 installutil exe 的情况下以编程方式安装 Windows 服务 您可以通过添加此代码 在程序文件 Program cs 中 来安装该服务 以便在使用指定参数从命令行运行时自行安装
  • 具有 openid 连接重定向的反向代理

    在我的应用程序中我集成了Identity server 3 with openid connect 在我们的生产服务器上 我们的网站位于反向代理后面 这会导致问题 当用户登录并被身份服务器重定向回来时 我们的应用程序希望将用户重定向到他的原
  • 如何在 JavaScript 中获取 css3 翻译后元素的位置?

    我在 stackoverflow 上看到了以两种不同形式发布的内容 但这些解决方案对我不起作用 本质上 我有一个要翻译的项目 当我执行 obj style left 或 obj offsetLeft 时 在元素被翻译后 我得到 0 无论如何
  • Docker:容器与本地安装

    在周末第一次使用 Docker 并看到 irssi mutt 浏览器等所有内容的小图像之后 我想知道本地安装的软件包是否正在为数十个容器让路 我可以看到保持基本系统非常干净以及拥有所有这些容器都是独立的并且可以轻松地重新定位到不同桌面 甚至
  • 将 pandas join 中的列后缀转换为 MultiIndex

    我有两个 pandas DataFrame 它们具有 不一定 相同的索引和列名称 gt gt gt df L pd DataFrame X 1 3 Y 5 7 gt gt gt df R pd DataFrame X 2 4 Y 6 8 我
  • 如果未安装应用程序,如何从深层链接重定向到应用程序商店?

    我希望用户能够通过 Facebook 等共享链接 例如 app com SKFLA 这主要是因为深层链接本身不可点击 单击时 会重定向到深层链接应用程序 SKFLA 如果安装了该应用程序 则会打开该应用程序 到目前为止一切正常 但如果该应用
  • Javascript / CSS:设置(firefox)iframe 的缩放级别?

    我想创建一个包含多个显示不同页面的 iframe 的页面 一种 并排浏览多个页面 类型的东西 问题是这样做时 视口非常小 我只能看到每个页面的左上角 有没有办法设置 iframe 来有效地执行 Firefox 的缩小 ctrl 减号 几次
  • 如何在Java中向文件写入换行符

    我有一个包含新行的字符串 我将此字符串发送到一个函数 以将字符串写入文本文件 如下所示 public static void writeResult String writeFileName String text try FileWrit
  • 按等级排列的 FindBugs 2.0 错误列表?

    我知道有list http findbugs sourceforge net bugDescriptions html错误 但我想要一个包含有关排名 版本 2 0 中为 1 到 20 或至少有关排名组 令人担忧 令人不安 可怕 最可怕 的附
  • 在SecurityManager下创建对象时出现NoClassDefFoundError

    我试图通过在非常严格的 SecurityManager 下运行处理用户提供的内容的代码来保护我的应用程序 它是 AccessController doPrivileged 的本质 通常这用于提供具有额外权限的代码块 但我使用它来将代码块限制
  • Spring Boot 日志中缺少应用程序名称

    例如 人们通常会得到这样的内容 my service id 是应用程序名称 2016 02 11 17 12 45 404 INFO my service id 85184 nio 8080 exec 1 com example MySim
  • SQL Server 2014 合并重叠的日期范围

    我在 SQL Server 2014 数据库中有一个包含 200 000 行的表 如下所示 CREATE TABLE DateRanges Contract VARCHAR 8 Sector VARCHAR 8 StartDate DATE