回填日期在SQL Server中使用CTE

时间:2017-07-19 18:49:47

标签: sql-server common-table-expression

我有一个带有ID和null startdate的表。我想用CTE回填它们。

如果EndDate是' 2011-12-31'对于记录#1,记录#2的StartDate是记录#1 + 1天的EndDate,即' 2012-01-01'

Create table dbo.input(inputid int null,startDate smalldatetime null,endDate smalldatetime null)
 insert into dbo.input values(111,null,'2011-05-31')
 insert into dbo.input values(111,null,'2012-05-31')
 insert into dbo.input values(111,null,'2013-05-31')
 insert into dbo.input values(111,null,'2014-05-31')
 insert into dbo.input values(111,null,'2015-05-31')


 insert into dbo.input values(222,null,'2010-06-30')
 insert into dbo.input values(222,null,'2011-06-30')
 insert into dbo.input values(222,null,'2012-06-30')
 insert into dbo.input values(222,null,'2013-06-30')
 insert into dbo.input values(222,null,'2014-06-30')

这是预期的输出。

 Create table dbo.output(outputid int null,startDate smalldatetime null,endDate smalldatetime null)
 insert into dbo.output(111,null,'2011-05-31')
 insert into dbo.output(111,'2011-06-01','2012-05-31')
 insert into dbo.output(111,'2012-05-31','2013-05-31')
 insert into dbo.output(111,'2013-05-31','2014-05-31')
 insert into dbo.output(111,'2014-05-31','2015-05-31')


 insert into dbo.output(222,null,'2010-06-30')
 insert into dbo.output(222,'2010-06-30','2011-06-30')
 insert into dbo.output(222,'2011-06-30','2012-06-30')
 insert into dbo.output(222,'2012-06-30','2013-06-30')
 insert into dbo.output(222,'2013-06-30','2014-06-30')

这就是我试过的

WITH CTE AS (
 SELECT
        rn = ROW_NUMBER() OVER (partition by p.inputid ORDER BY p.inputid,endDate),
        p.inputid
       ,EndDate
FROM dbo.input p
)
SELECT distinct
DATEADD(day,1,prev.enddate) as startd,cte.inputid,cte.endDate
FROM CTE
LEFT JOIN CTE prev ON prev.rn = CTE.rn - 1
LEFT JOIN CTE nex ON nex.rn = CTE.rn + 1
order by cte.inputid,startd

没有正确地对inputid进行分组,我不知道如何解决这个问题?

感谢任何帮助。

由于 MR

2 个答案:

答案 0 :(得分:1)

调整现有查询,但结果与预期不完全相同。 StartDate应该是之前EndDate的第二天吗? (与前一个EndDate不同。)

;WITH cte AS (SELECT
                   rn = ROW_NUMBER() OVER (partition by inputid ORDER BY endDate)
               , *
            FROM #input 
)

SELECT a.inputid, DATEADD(DD, 1, b.endDate) as startDate , a.endDate
FROM CTE a
LEFT JOIN CTE b 
    ON  a.inputid = b.inputid and a.rn = b.rn + 1
ORDER BY a.inputid, a.startDate;

答案 1 :(得分:0)

只要您使用的是SQL Server 2012或更高版本,就可以使用以下内容...

 SELECT 
    i.inputid,
    startDate = DATEADD(dd, 
                        CASE WHEN ROW_NUMBER() OVER (ORDER BY i.inputid, i.endDate) = 2 THEN 1 ELSE 0 END, 
                        LAG(i.endDate, 1) OVER (PARTITION BY i.inputid ORDER BY i.endDate)
                        ),
    i.endDate
 FROM 
    #input i;