我得到了表#a,如下所示:
ID | TYPE_ID | CREATED_DT
============================
001 | 111 | 2019-08-28
001 | 111 | 2018-08-12
001 | 111 | 2017-08-23
001 | 111 | 2016-08-14
001 | 111 | 2015-08-17
001 | 111 | 2014-08-11
001 | 112 | 2019-05-31
001 | 112 | 2018-05-28
我希望得到如下最终结果:
ID | TYPE_ID | CREATED_DT
============================
001 | 111 | 2019-08-28
001 | 111 | 2018-08-12
001 | 111 | 2017-08-23
001 | 111 | 2016-08-14
001 | 111 | 2015-08-17
001 | 111 | 2014-08-11
001 | 112 | 2019-05-31
001 | 112 | 2018-05-28
001 | 112 | 2017-05-31 --Predict YEAR end dates if not available
001 | 112 | 2016-05-31
001 | 112 | 2015-05-31
001 | 112 | 2014-05-31
如果没有可用日期,则最终结果集应根据每个TYPE_ID预测最多6个月的结束日期(TYPE_ID = 112仅具有2个可用日期)。我确定我们可以使用DATEADD和DATEDIFF函数来预测日期,但是据我所知有点复杂。有帮助吗?
我正在尝试的查询,但不完全是:
select *,
ROW_NUMBER() OVER(PARTITION BY ID, TYPE_ID ORDER BY CREATED_DT DESC) AS RN
INTO #B
from #a;
;WITH CTE(ID, TYPE_ID, CREATED_DT, RN)
AS(
SELECT
ID,
TYPE_ID,
CREATED_DT,
RN
FROM #B
WHERE RN = 1 --Instead of RN = 1 I would like to get this till all
--available dates, so that I can go to recursive part for
--predicting non-available dates
UNION ALL
SELECT
A.ID,
A.TYPE_ID,
DATEADD(yy, -1, CTE.CREATED_DT)AS CREATED_DT,
CTE.RN +1 AS RN
FROM #B AS A
INNER JOIN CTE ON CTE.ID = A.ID
AND CTE.TYPE_ID = A.TYPE_ID
AND CTE.RN < 6
AND A.RN = 1
)
由于没有标识每行的ID,您可以使用等级窗口功能获取该表的最后一行。然后,从最后一行日期开始,您可以根据排名将-1年添加到每个日期。然后在UNION结束时将初始CTE与预测CTE结合起来。
;WITH CTE
AS (
SELECT d.ID
,d.Type_ID
,d.CREATED_DT
,RANK() OVER (
ORDER BY Type_ID
,Created_DT
) AS OrderOf
FROM datetable d
)
,CTE2
AS (
SELECT M.ID
,m.Type_ID
,DATEADD(Year, - 1, m.CREATED_DT) AS Created_DT
,M.OrderOf + 1 AS OrderOf
FROM CTE M
WHERE OrderOf = 8
)
,CTE3 (
n
,ID
,Type_Id
,Created_DT
,OrderOf
)
AS (
SELECT 0
,M.ID
,m.Type_ID
,m.CREATED_DT
,M.OrderOf AS OrderOf
FROM CTE2 M
UNION ALL
SELECT n + 1
,T.ID
,T.Type_ID
,DATEADD(YEAR, - 1, T.CREATED_DT)
,T.OrderOf + 1 AS OrderOf
FROM CTE3 T
WHERE n < 4
)
SELECT ID
,Type_ID
,Created_DT
FROM CTE3
UNION
SELECT ID
,Type_ID
,Created_DT
FROM CTE
ORDER BY Type_Id
,Created_DT DESC;