我正在寻找一个解决方案,我必须使用另一个表中的数据从一个记录创建一组记录。表定义:
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)中执行此操作
关于如何将其写为选择以使光标的开销消失的任何想法?
答案 0 :(得分:3)
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