Как получить значение поля до его последнего изменения в db2? - PullRequest
0 голосов
/ 25 сентября 2019

У меня есть таблица, содержащая nationalcode, status, changestatusdate.Я хочу получить последний status и второй последний status для каждого nationalcode, но у меня есть проблема:

Для некоторых из nationalcode, changestatusdate изменилось и получено новое значение, но statusне изменилось, поэтому мы не можем использовать changestatusdate для отображения изменения статуса.Например, у нас есть эти данные:

[nationalcode]       [status]   [changestatusdate]
[123]                  [1]          [20150101]
[123]                  [2]          [20150301]
[123]                  [2]          [20150315]
[123]                  [3]          [20150601]
[123]                  [1]          [20151201]
[123]                  [5]          [20160101]
[123]                  [5]          [20160301]

введите описание изображения здесь

Нам нужен последний status(5) и второй последний status(1) .... как можномы получаем эти данные?

Ответы [ 3 ]

0 голосов
/ 25 сентября 2019

Это не красиво, но вы получите последние и вторые до последних status значений для каждого nationalcode:

SELECT status
FROM (
  SELECT nationalcode, status, changestatusdate,
    ROW_NUMBER OVER(
      PARTITION BY nationalcode -- Group rows by nationalcode
      ORDER BY changestatusdate DESC -- Order by most recent
    ) AS RowNum
  FROM (
    SELECT nationalcode, status, changestatusdate, 
      ROW_NUMBER() OVER(
        PARTITION BY nationalcode, status -- Group rows by (nationalcode, status)
        ORDER BY changestatusdate DESC -- Order by most recent
      ) AS RowNum
    FROM mytable
  ) src
  WHERE RowNum = 1 -- Get most recent row
) src
WHERE RowNum <= 2 -- Get two most recent rows
0 голосов
/ 25 сентября 2019

Попробуйте это:

/*
WITH MYTABLE (nationalcode, status, changestatusdate) AS
(
VALUES
  (123, 1, 20150101)
, (123, 2, 20150301)
, (123, 2, 20150315)
, (123, 3, 20150601)
, (123, 1, 20151201)
, (123, 5, 20160101)
, (123, 5, 20160301)
)
*/
SELECT DISTINCT nationalcode, status
FROM 
(
  SELECT 
    T.nationalcode, T.status
  , SUM
  (
    CASE WHEN STATUS = COALESCE
    (
      MAX(status) OVER (PARTITION BY nationalcode ORDER BY changestatusdate DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
    , STATUS
    ) THEN 0 ELSE 1 END
  ) OVER (PARTITION BY nationalcode ORDER BY changestatusdate DESC) FLAG
  FROM MYTABLE T
)
WHERE FLAG < 2
;
0 голосов
/ 25 сентября 2019

Я предлагаю следующий подход:

  • Фильтруйте данные, чтобы в соседних строках не было повторяющихся состояний.
  • Перечислите строки так, чтобы последний статус был "1",рядом с последним «2» и т. д.
  • Использовать условное агрегирование.

В запросе это выглядит следующим образом:

select t.national_code,
       max(case when seqnum = 1 then status end) as last_status,
       max(case when seqnum = 2 then status end) as last_status_but_one
from (select t.*,
             row_number() over (partition by national_code order changestatusdate desc) as seqnum
      from (select t.*,
                   lag(status) over (partition by national_code order by changestatusdate) as prev_status
            from t
           ) t
      where prev_status is null or prev_status <> status
     ) t
where seqnum <= 2
group by national_code;
...