SQL 中的日期范围交集分割

2024-01-09

我有一个 SQL Server 2005 数据库,其中包含一个名为“成员资格”的表。

表架构为:

PersonID int, Surname nvarchar(30), FirstName nvarchar(30), Description nvarchar(100), StartDate datetime, EndDate datetime

我目前正在开发一个网格功能,该功能可以按人员显示会员资格细目。要求之一是拆分存在日期范围交集的成员资格行。交集必须受姓氏和名字约束,即分割仅发生在具有相同姓氏和名字的成员记录中。

表数据示例:


18  Smith  John  Poker Club  01/01/2009  NULL
18  Smith  John  Library     05/01/2009  18/01/2009
18  Smith  John  Gym         10/01/2009  28/01/2009
26  Adams  Jane  Pilates     03/01/2009  16/02/2009  

预期结果集:


18  Smith  John  Poker Club                  01/01/2009  04/01/2009
18  Smith  John  Poker Club / Library        05/01/2009  09/01/2009
18  Smith  John  Poker Club / Library / Gym  10/01/2009  18/01/2009
18  Smith  John  Poker Club / Gym            19/01/2009  28/01/2009
18  Smith  John  Poker Club                  29/01/2009  NULL
26  Adams  Jane  Pilates                     03/01/2009  16/02/2009  

有谁知道我如何编写一个存储过程来返回具有上述细分的结果集。


对于这个问题,您将遇到的问题是,随着数据集的增长,使用 TSQL 解决它的解决方案将无法很好地扩展。下面使用一系列动态构建的临时表来解决该问题。它使用数字表将每个日期范围条目拆分为各自的日期。这是它无法扩展的地方,主要是因为您的开放范围 NULL 值看起来无穷大,因此您必须将固定日期交换到遥远的未来,从而将转换范围限制为可行的时间长度。通过构建具有适当索引的日期表或日历表来优化每天的渲染,您可能会看到更好的性能。

拆分范围后,将使用 XML PATH 合并描述,以便范围系列中的每一天都包含为其列出的所有描述。按 PersonID 和日期进行行编号允许使用两个 NOT EXISTS 检查来查找每个范围的第一行和最后一行,以查找匹配的 PersonID 和描述集的前一行不存在的实例,或者下一行不存在的实例不存在匹配的 PersonID 和 Description 集。

然后使用 ROW_NUMBER 对该结果集重新编号,以便将它们配对以构建最终结果。

/*
SET DATEFORMAT dmy
USE tempdb;
GO
CREATE TABLE Schedule
( PersonID int, 
 Surname nvarchar(30), 
 FirstName nvarchar(30), 
 Description nvarchar(100), 
 StartDate datetime, 
 EndDate datetime)
GO
INSERT INTO Schedule VALUES (18, 'Smith', 'John', 'Poker Club', '01/01/2009', NULL)
INSERT INTO Schedule VALUES (18, 'Smith', 'John', 'Library', '05/01/2009', '18/01/2009')
INSERT INTO Schedule VALUES (18, 'Smith', 'John', 'Gym', '10/01/2009', '28/01/2009')
INSERT INTO Schedule VALUES (26, 'Adams', 'Jane', 'Pilates', '03/01/2009', '16/02/2009')
GO

*/

SELECT 
 PersonID, 
 Description, 
 theDate
INTO #SplitRanges
FROM Schedule, (SELECT DATEADD(dd, number, '01/01/2008') AS theDate
    FROM master..spt_values
    WHERE type = N'P') AS DayTab
WHERE theDate >= StartDate 
  AND theDate <= isnull(EndDate, '31/12/2012')

SELECT 
 ROW_NUMBER() OVER (ORDER BY PersonID, theDate) AS rowid,
 PersonID, 
 theDate, 
 STUFF((
  SELECT '/' + Description
  FROM #SplitRanges AS s
  WHERE s.PersonID = sr.PersonID 
    AND s.theDate = sr.theDate
  FOR XML PATH('')
  ), 1, 1,'') AS Descriptions
INTO #MergedDescriptions
FROM #SplitRanges AS sr
GROUP BY PersonID, theDate


SELECT 
 ROW_NUMBER() OVER (ORDER BY PersonID, theDate) AS ID, 
 *
INTO #InterimResults
FROM
(
 SELECT * 
 FROM #MergedDescriptions AS t1
 WHERE NOT EXISTS 
  (SELECT 1 
   FROM #MergedDescriptions AS t2 
   WHERE t1.PersonID = t2.PersonID 
     AND t1.RowID - 1 = t2.RowID 
     AND t1.Descriptions = t2.Descriptions)
UNION ALL
 SELECT * 
 FROM #MergedDescriptions AS t1
 WHERE NOT EXISTS 
  (SELECT 1 
   FROM #MergedDescriptions AS t2 
   WHERE t1.PersonID = t2.PersonID 
     AND t1.RowID = t2.RowID - 1
     AND t1.Descriptions = t2.Descriptions)
) AS t

SELECT DISTINCT 
 PersonID, 
 Surname, 
 FirstName
INTO #DistinctPerson
FROM Schedule

SELECT 
 t1.PersonID, 
 dp.Surname, 
 dp.FirstName, 
 t1.Descriptions, 
 t1.theDate AS StartDate, 
 CASE 
  WHEN t2.theDate = '31/12/2012' THEN NULL 
  ELSE t2.theDate 
 END AS EndDate
FROM #DistinctPerson AS dp
JOIN #InterimResults AS t1 
 ON t1.PersonID = dp.PersonID
JOIN #InterimResults AS t2 
 ON t2.PersonID = t1.PersonID 
  AND t1.ID + 1 = t2.ID 
  AND t1.Descriptions = t2.Descriptions

DROP TABLE #SplitRanges
DROP TABLE #MergedDescriptions
DROP TABLE #DistinctPerson
DROP TABLE #InterimResults

/*

DROP TABLE Schedule

*/

上述解决方案还将处理其他描述之间的间隙,因此如果您要为 PersonID 18 添加另一个描述,留下间隙:

INSERT INTO Schedule VALUES (18, 'Smith', 'John', 'Gym', '10/02/2009', '28/02/2009')

它将适当地填补空白。正如评论中所指出的,您不应该在此表中包含姓名信息,它应该标准化为可以在最终结果中联接的人员表。我通过使用 SELECT DISTINCT 构建临时表来创建该 JOIN 来模拟另一个表。

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

SQL 中的日期范围交集分割 的相关文章

  • FROM 子句中子查询末尾随机字母的含义 - SQL

    我终于成功将两个sql sum查询的结果求和了 这家伙迈出了一小步 我的问题与代码中的最后一个字符 Z 有关 SELECT SUM hr FROM SELECT SUM amount AS hr FROM Try again dbo tue
  • 如何在浏览时检查客户端是否安装了 SQLNCLI10 提供程序?

    我有一个 C 网站 允许客户端从其 PC 直接连接到远程 SQL Server 数据库 通过使用第 3 方 ActiveX 控件绕过 Web 服务器 我最初使用的是SQLOLEDB提供商并且运行良好 客户端位于内部网络中 使用 Window
  • 比较 2 个 linq 应用程序:意外结果

    我起草了2 ASP NET应用程序 using LINQ 一个连接到微软SQL服务器 另一个对某些专有内存结构 这两个应用程序都可以使用以下表格3 个 int 字段 有500 000 条记录 内存结构与 SQL Server 表相同 使用的
  • SQL Server:读取数据库图表的权限

    您能否告知 授予用户读取 SQL Server 2005 中数据库图表的权限需要什么权限 多谢 From BOL http msdn microsoft com en us library ms186345 28SQL 90 29 aspx
  • 字符串被两个不同的分隔符分割

    我有这样的字符串 some dasd dasd dasdas dasdas dasd das dsad 我需要用两个不同的符号将字符串拆分为数组 and 所以我想得到数组 some dasd dasd dasdas dasdas dasd
  • 有没有办法让这个UDF具有确定性?

    我认为这不是确定性的 因为DB NAME 是不是确定性的 如果DB NAME 不是确定性的 为什么不是确定性的 ALTER FUNCTION TheSchema udf IS PRODUCTION RETURNS bit WITH SCHE
  • Pandas read_sql 读取时更改大量 ID

    我将 Oracle 数据库转移到 SQL Server 一切似乎都很顺利 各种 ID 列都是很大的数字 因此我不得不使用 Decimal 因为它们对于 BigInt 来说太大了 我现在尝试使用 pandas read sql 使用 pyod
  • 帮助将二进制图像数据从 SQL Server 读取到 PHP 中

    我似乎无法找到将二进制数据从 SQL 服务器读取到 PHP 的方法 我正在开发一个项目 需要能够将图像直接存储在 SQL 表中 而不是文件系统上 目前 我一直在使用这样的查询 插入 myTable 文档 选择 从 OPENROWSET BU
  • T-SQL 相当于 =rand()

    我有几个内容表 我想用随机的文本段落填充它们 在 MS Word 中 我只需输入 rand 即可 我收到三段新鲜的文字 是否有 SQL 脚本 命令可用于使用 t sql 生成随机字典单词 declare Lorem nvarchar max
  • 如何在存储过程中使用名称求和和分组?

    我想对钱列求和 但我想要状态中的组名称和代码 这是存储过程代码 Sql Server 2008 SELECT um upmoney as money um pId as code um FName as name up status as
  • 默认情况下 dbo 架构中的 EF 6 Code First __MigrationHistory

    我是代码优先实体框架的新手 第一次运行我的应用程序后登录数据库时 当我看到 MigrationHistory 表时 我有点困惑 我现在了解对此表的需求 但不喜欢它位于用户表内的标准 dbo 模式中 我认为它很唐突且有风险 我的第一个想法是将
  • 从多行中获取/选择值到sql server中的1行中

    我有一个表格 每列都有一些图像 Acd unq id Emp unq id Acd BImg1 Acd BImg2 Acd RImg1 Acd RImp2 Acd RImg3 Acd Active 1 1745 BinaryImg Bina
  • Linq 选择与另一个表中的 ID 相等的项目

    我不确定这怎么可能 但我有两个表 我想通过表 1 的值从表 2 中获取值 表 1 有一个名为 rank 的外键 它是int 表 2 有一个名为 name 的值 它是string 现在表 1 的 排名 与表 2 的 ID 相关 所以当我说 v
  • ELMAH 错误和经典 Asp

    我们已经在我们拥有的 ASP NET MVC 网站上使用 ELMAH 进行错误日志记录 但我们的主网站仍然是经典的 asp 我已经开始为该网站创建错误处理 日志记录结构 但我认为它如果我们能够在所有应用程序中保持错误日志记录的一致性 那就太
  • T-SQL 中结果集的幂集(所有组合)

    我需要一个 t sql 代码来获取结果集的幂集 输入示例 ColumnName 1 2 3 Example Output one columns as nvarchar 1 2 3 1 2 1 3 2 3 1 2 3 输出集可能包含重复值
  • 随机排列每行的列值

    我正在使用 C NET 开发多项选择题考试生成器 每次做出报告时 都会在数据库中随机挑选问题 并随机调整选项 我可以做随机问题部分 但我不能做选择的洗牌 我有一张表 其中一行如下 question answer distractor1 di
  • 从 bak 文件恢复数据库 sql server 的脚本不起作用

    我有一个空数据库 DB Clients 我想从一个恢复数据库 bak file OldDBClients bak 这是路径 C OldDBClients bak 这是我的脚本 USE master GO RESTORE DATABASE D
  • TSQL:无法对 COUNT(*) 执行聚合函数 AVG 来查找一天中最繁忙的时间

    考虑一个保存日志数据的 SQL Server 表 重要的部分是 CREATE TABLE dbo CustomerLog ID int IDENTITY 1 1 NOT NULL CustID int NOT NULL VisitDate
  • 如何在 SQL Server 2008 中使用 GUID 数据类型?

    我想使用建立一个员工表SQL SERVER 2008 在我的表中 我希望为每个员工提供一个 ID 我听说过GUID我有点明白它是一种数据类型 但我无法使用它 你能告诉我使用它的方法吗 顺便说一句 假设我想要这样的东西 CREATE TABL
  • 如何在SQL Compact Edition中导入数据? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我似乎没有找到合适的工具 也没有找到

随机推荐

  • 如何从 JQUERY 移动列表视图中删除元素

    有一个列表视图 它在加载页面时动态加载 这会在列表视图中添加元素 问题是我放置了后退按钮 在转到上一个屏幕并返回到当前屏幕后 它正在加载数据并附加到列表视图 I need to remove the li elements from the
  • PHP 将数组提取到变量中

    我有以下输出我试图将各个值放入单独的变量中 output Array 0 gt Array 0 gt 8711 1 gt 200 2 gt 755 3 gt 1800 4 gt 01 5 gt 675 6 gt 8910 我尝试过以下代码但
  • 无法将变量添加到以下划线开头的表中(Laravel)

    我无法向 MySQL 添加值 因为行名称以 开头 SQLSTATE HY000 一般错误 1364 字段 user id 没有 默认值 我无法更改 SQL 表首选项 因为我们正在使用旧数据库编写新项目 attributes request
  • 在sql server中将列转换为行及其各自的数据

    我有一个场景 我需要将表的列转换为行 例如 表 库存 ScripName ScripCode Price 20 MICRONS 533022 39 我需要用以下格式表示表格 但我只需要这种单行表示 ColName ColValue Scri
  • 寻找 RSS 应用程序的 Google Reader 同步替代方案

    我正处于设计 RSS 应用程序的早期阶段 我希望将同步到在线 RSS 提要服务作为一项功能 大多数此类应用程序都利用 Google Reader 的提要 同步功能 但 Google 现在正在将同步功能从 Reader 服务中移出 而且其 A
  • React:访问React内部操作队列

    React 收集操作 https reactjs org docs implementation notes html updating host components 就像 ADD REPLACE REMOVE 等 DOM 操作一样 这样
  • 如何使用最新的 Facebook sdk 从 iOS 中的 Facebook API 获取用户的生日?

    如何使用最新的 Facebook sdk 从 iOS 中的 Facebook API 获取用户的生日 我尝试去获取它 fields id name link first name last name picture type large e
  • 如何从 Java 代码更新 Jenkins config.xml?

    我是 Jenkins 插件开发的新手 所以如果问题很愚蠢 请原谅我 我目前正在开发一个 Jenkins 插件 它提供了一个非常小的配置选项列表 如所附屏幕截图所示 该表单是使用 Jelly 脚本设计的 我必须从我的 Java 代码更新作业的
  • Tensorflow 中的 zip 之类的函数? Tensorflow张量运算

    我的问题是关于 Tensorflow 中的张量运算 比方说 import tensorflow as tf import numpy as np a tf Variable np random random 10 3 3 b tf Vari
  • Javascript d3:有没有办法以编程方式停止拖动项目?

    当我单击并拖动项目时 有没有办法在不松开鼠标按钮的情况下强制使其停止可拖动 例如 如果我将一个项目拖过某个边界框 我可以让它放开所拖动的项目吗 jsfiddle 示例 http jsfiddle net typeofgraphic Ne8h
  • 在 Sublime Text 中编写查找和替换操作脚本

    我经常发现自己在文件中执行重复的文件和替换操作 最常见的是fixed查找和替换操作 删除一些行 更改一些始终相同的字符串等等 在 Vim 中这是理所当然的 function Modify Strength Files execute s e
  • 使用 ProGuard 和 Firebase Auth 进行 Flutter 构建崩溃

    我跟着有关将 ProGuard 添加到 Flutter 的说明 https flutter io android release step 1 configure proguard现在在启动应用程序时看到此异常 java lang NoCl
  • 硒下载文件

    我正在尝试制作一个 Selenium 程序来自动下载和上传一些文件 请注意 我这样做不是为了测试 而是为了尝试自动化某些任务 这是我对 Firefox 配置文件的 set preference profile set preference
  • ASP.NET MVC 2.0 JsonRequestBehavior 全局设置

    默认情况下 当操作尝试返回 JSON 以响应 GET 请求时 ASP NET MVC 2 0 现在将引发异常 我知道这可以通过使用 JsonRequestBehavior AllowGet 逐个方法地覆盖 但是是否可以在控制器或更高的基础上
  • .htaccess 将 https 重定向到 http 不起作用

    我正在尝试捕获到我的网站前面的任何 https 流量 因此 https www domain com 被重定向到 http www domain com 然而 其他子域需要重定向到其他地方 在大多数情况下 除了 https gt http
  • 域名指向单个页面

    我试图将域名指向单个页面 并保持域名相同 无重定向 因此 如果用户输入 www domain1 com au gt 将显示原始站点 如果用户输入 www domain2 com au gt 他们会显示 www domain1 com au
  • ubuntu:sem_timedwait 未唤醒 (C)

    我有3个进程需要同步 进程一执行某项操作 然后唤醒进程二并休眠 进程二执行某项操作 然后唤醒进程三并休眠 进程三执行某项操作 唤醒进程一并休眠 整个循环定时运行在 25hz 左右 由于在我的 真实 应用程序中触发进程二之前 外部同步到进程一
  • 使用CodeIgniter从mysql数据库中随机记录

    我在互联网上进行了研究 但找不到任何东西 我有一个 mysql 数据库 并在一个表中记录 我需要在每次页面加载时从该表中获取随机记录 我怎样才能做到这一点 有什么功能吗 欣赏 谢谢 已排序 关联 http www derekallard c
  • 在 Python 或 C++ 中单声道播放 Mp3

    我正在编码音乐播放器 https github com fabiomdiniz Gokya 2 The Super Gokya 在 python 中使用 pyqt 我希望它能够单声道播放 mp3 文件 我已经使用 pygame 完成了这一点
  • SQL 中的日期范围交集分割

    我有一个 SQL Server 2005 数据库 其中包含一个名为 成员资格 的表 表架构为 PersonID int Surname nvarchar 30 FirstName nvarchar 30 Description nvarch