代码之家  ›  专栏  ›  技术社区  ›  Tim Mahy

在开始/结束日期拆分多个记录中的记录

  •  4
  • Tim Mahy  · 技术社区  · 14 年前

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

    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)中使用它

    关于如何将其写为select以使光标的开销消失有什么想法吗?

    1 回复  |  直到 13 年前
        1
  •  3
  •   Anthony Faull    14 年前
    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