sql-server - 在开始/结束日期将记录拆分为多个记录

标签 sql-server datetime stored-procedures

我正在寻找一种解决方案,我必须使用另一个表中的数据从一个记录创建一组记录。表定义:

DECLARE A AS TABLE
(
 AID BIGINT NOT NULL,
 StartDate DATETIME NOT NULL,
 EndDate DATETIME
)

DECLARE B AS TABLE
(
 AID BIGINT NOT NULL,
 StartDate DATETIME NOT NULL,
 EndDate DATETIME NULL
)

这个想法是,当 A 包含:

1 | 01-01-2010 | 01-02-2010
2 | 01-10-2010 | 31-10-2010

B 包含:

1 | 01-01-2010 | 15-01-2010
2 | 15-10-2010 | 20-10-2010

我们收到 5 条记录:

1 | 01-01-2010 | 15-01-2010
1 | 16-01-2010 | 01-02-2010
2 | 01-10-2010 | 15-10-2010
2 | 16-10-2010 | 20-10-2010
2 | 21-10-2010 | 31-10-2010

目前,我们使用 A 上的游标和 B 上的内循环游标来执行此操作,我们必须在 SQLServer(TSQL 或最坏情况下的 CLR)中执行此操作

关于如何将其编写为选择以便光标的开销消失的任何想法?

最佳答案

DECLARE @A TABLE (AID BIGINT NOT NULL, StartDate DATETIME NOT NULL, EndDate DATETIME)
DECLARE @B TABLE (AID BIGINT NOT NULL, StartDate DATETIME NOT NULL, EndDate DATETIME NULL)

SET DATEFORMAT dmy
INSERT @A VALUES (1 ,'01-01-2010','01-02-2010')
INSERT @A VALUES (2 ,'01-10-2010','31-10-2010')
INSERT @B VALUES (1 ,'01-01-2010','15-01-2010')
INSERT @B VALUES (2 ,'15-10-2010','20-10-2010')

;WITH transitions as
(
    SELECT *, ROW_NUMBER() OVER (PARTITION BY AID ORDER BY startdate) Sequence
    FROM (
        SELECT A.AID, A.startdate
        FROM @a A
        UNION
        SELECT A.AID, B.startdate + 1
        FROM @A A
        INNER JOIN @b B ON B.startdate > A.startdate AND B.startdate < A.enddate
        UNION
        SELECT A.AID, B.enddate + 1
        FROM @A A
        INNER JOIN @b B ON B.enddate > A.startdate AND B.enddate < A.enddate
        UNION
        SELECT A.AID, A.enddate + 1
        FROM @a A
        WHERE A.enddate > A.startdate
    ) T
)   
SELECT T1.AID, T1.startdate startdate, T2.startdate - 1 enddate
FROM transitions T1
INNER JOIN transitions T2 ON T2.AID = T1.AID AND T2.Sequence = T1.Sequence + 1
ORDER BY T1.AID, T1.Sequence

关于sql-server - 在开始/结束日期将记录拆分为多个记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4245513/

相关文章:

c# - 如何在运行时根据现有数据模型中的数据构建自定义的动态 ViewModel?

sql-server - 将 varchar 值 'N' 转换为数据类型 int 时转换失败

SQL - 查找列之间的差异

datetime - 如何为 d3.js 配置时间范围

c# - 在 C# 中从字符串到日期解析?

java - 比较java和mysql日期时间之间的秒差

c# - 如何使用MySql中的动态查询将数据插入临时表

sql - CREATE OR ALTER PROCEDURE 中关键字 'OR' 附近的语法不正确

mysql - 创建MySQL存储过程的问题

.net - 如果数据库中的所有列都是 varchars,使用 SqlDbType.VarChar 而不是 SqlDbType.NVarChar 有什么好处