SQL-获取不可用的预测日期

问题描述 投票:0回答:1

我得到了表#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
)
sql sql-server-2008 select common-table-expression dateadd
1个回答
0
投票

由于没有标识每行的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;
© www.soinside.com 2019 - 2024. All rights reserved.