SQL - получить прогнозируемые даты, если они недоступны - PullRequest
0 голосов
/ 04 ноября 2019

Я получил таблицу #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

Окончательный набор результатов должен прогнозировать даты до 6даты окончания месяца по TYPE_ID, если даты недоступны (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
)

1 Ответ

0 голосов
/ 05 ноября 2019

Поскольку нет идентификатора для идентификации каждой строки, вы можете использовать функцию окна ранга, чтобы взять последнюю строку в этой таблице. Затем с даты последней строки вы можете датировать -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;
...