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

У меня есть таблица, которая выглядит примерно так, где идентификаторы отображаются со старым значением с новым значением (то, которое только что было изменено).

IF OBJECT_ID('tempdb.dbo.#TT','U')IS NOT NULL
    DROP TABLE #TT;

SELECT *
INTO #TT
FROM (
SELECT 1 AS ID, 'A' AS OldValue, 'B' AS NewValue, CONVERT(DATE,'20190421') AS [Date]
UNION ALL
SELECT 1 AS ID, 'B' AS OldValue, 'C' AS NewValue, CONVERT(DATE,'20190423') AS [Date]
UNION ALL
SELECT 2 AS ID, 'D' AS OldValue, 'E' AS NewValue, CONVERT(DATE,'20190422') AS [Date]
UNION ALL
SELECT 3 AS ID, 'J' AS OldValue, 'K' AS NewValue, CONVERT(DATE,'20190422') AS [Date]
UNION ALL
SELECT 3 AS ID, 'K' AS OldValue, 'L' AS NewValue, CONVERT(DATE,'20190423') AS [Date]
UNION ALL
SELECT 3 AS ID, 'L' AS OldValue, 'M' AS NewValue, CONVERT(DATE,'20190424') AS [Date]
) T
;

Я хочу отобразить каждый идентификатор и старыйзначение с новейшим значением, доступным для них.Например, ID = 1 и OldValue = A должны отображать C или ID = 3, а OldValue = K должно отображать M

Я попытался сделать рекурсивный cte следующим образом:

WITH RecCTE AS (
SELECT ID, OldValue, NewValue
FROM #TT
UNION ALL
SELECT A.ID, B.OldValue, A.NewValue
FROM #TT A
INNER JOIN RecCTE B ON A.ID = B.ID AND B.NewValue = A.OldValue
)

SELECT *
FROM RecCTE

С этимрекурсивный запрос.Я получаю некоторую строку правильно, но я также получаю дополнительные строки между:

|       ID  |   OldValue    |    NewValue    |
|-----------|---------------|----------------|
|       1   |      A        |       B        |
|       1   |      B        |       C        |
|       2   |      D        |       E        |
|       3   |      J        |       K        |
|       3   |      K        |       L        |
|       3   |      L        |       M        |
|       3   |      K        |       M        |
|       3   |      J        |       L        |
|       3   |      J        |       M        |
|       1   |      A        |       C        |

Я хочу получить такие результаты:

    |       ID  |   OldValue    |    NewValue    |
    |-----------|---------------|----------------|
    |       1   |      A        |       C        |
    |       1   |      B        |       C        |
    |       2   |      D        |       E        |
    |       3   |      J        |       M        |
    |       3   |      K        |       M        |
    |       3   |      L        |       M        |

Ответы [ 2 ]

0 голосов
/ 26 апреля 2019

Если данные работают так, как они выглядят, как они работают, следующее будет делать это без использования рекурсии:

;WITH cte as (
   --  List of all, ordered by ID, with the most recent being the first listed
   SELECT
       ID
      ,NewValue
      ,row_number() over (partition by Id order by Date desc)  Ranking
     from #TT
    )
select
   tt.Id
  ,tt.OldValue
  ,cte.NewValue
 from #TT  tt
  --  Join table to the "most recent" row for the ID
  inner join cte
   on cte.ID = tt.Id
    and cte.Ranking = 1
0 голосов
/ 26 апреля 2019

Я думаю, что последний ряд должен работать:

WITH RecCTE AS (
      SELECT ID, OldValue, NewValue, 1 as lev
      FROM #TT
      UNION ALL
      SELECT A.ID, B.OldValue, A.NewValue, lev + 1
      FROM #TT A JOIN
           RecCTE B
           ON A.ID = B.ID AND B.NewValue = A.OldValue
     )
SELECT *
FROM (SELECT r.*, ROW_NUMBER() OVER (PARTITION BY id, OldValue ORDER BY lev DESC) as seqnum
      FROM RecCTE r
     ) r
WHERE seqnum = 1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...