Выберите первую запись последней группы, когда есть повторяющиеся группы - PullRequest
0 голосов
/ 25 декабря 2018

Попытка выбрать первую запись из последних повторяющихся групп СОСТОЯНИЯ для каждого POLICY_ID.Как я могу это сделать?

Редактировать / Примечание: может быть более двух повторений состояния, как показано в последних трех строках.

Просмотр данных:

enter image description here

Желаемый вывод:

enter image description here

SQL для данных:

--drop table mytable;
create table mytable (ROW_ID Number(5), POLICY_ID Number(5), 
                      CHANGE_NO Number(5), STATUS VARCHAR(50), CHANGE_DATE DATE);

insert into mytable values (  81, 1, 1, 'A', date '2018-01-01');
insert into mytable values (  95, 1, 2, 'A', date '2018-01-02');
insert into mytable values ( 100, 1, 3, 'B', date '2018-01-03');
insert into mytable values ( 150, 1, 4, 'C', date '2018-01-04');
insert into mytable values ( 165, 1, 5, 'A', date '2018-01-05');
insert into mytable values ( 175, 1, 6, 'A', date '2018-01-06');
insert into mytable values ( 599, 2, 1, 'S', date '2018-01-11');
insert into mytable values ( 602, 2, 2, 'S', date '2018-01-12');
insert into mytable values ( 611, 2, 3, 'S', date '2018-01-13');
insert into mytable values ( 629, 2, 4, 'T', date '2018-01-14');
insert into mytable values ( 720, 2, 5, 'U', date '2018-01-15');
insert into mytable values ( 790, 2, 6, 'S', date '2018-01-16');
insert into mytable values ( 812, 2, 7, 'S', date '2018-01-17');
insert into mytable values ( 825, 2, 8, 'S', date '2018-01-18');

select * from mytable;

Ответы [ 4 ]

0 голосов
/ 26 декабря 2018

Другой подход с match_recognize:

select row_id, policy_id, change_no, status, change_date
from   mytable
       match_recognize (
           partition by policy_id
           order by change_date
           measures
             strt.row_id as row_id
           , strt.change_no as change_no
           , strt.change_date as change_date
           , strt.status as status
           pattern (strt unchanged* final)
           define
             unchanged as next(unchanged.status) = prev(unchanged.status)
           , final as next(final.status) is null
      ) mr
order by mr.policy_id;
0 голосов
/ 25 декабря 2018

Вы можете использовать функции LEAD и LAG, чтобы идентифицировать строки, которые начинают «повторение».Условие status <> previous status and status = next status идентифицирует такие строки.

SELECT *
FROM (
    SELECT cte1.*, ROW_NUMBER() OVER (PARTITION BY POLICY_ID ORDER BY CHANGE_DATE DESC) AS rn
    FROM (
            SELECT mytable.*, CASE WHEN
                STATUS <> LAG(STATUS, 1, '!') OVER (PARTITION BY POLICY_ID ORDER BY CHANGE_DATE) AND
                STATUS = LEAD(STATUS) OVER (PARTITION BY POLICY_ID ORDER BY CHANGE_DATE)
            THEN 1 END AS toselect
            FROM mytable
    ) cte1
    WHERE toselect = 1
) cte2
WHERE rn = 1
0 голосов
/ 26 декабря 2018

Если вы используете Oracle 12c, вы можете использовать MATCH_RECOGNIZE:

SELECT ROW_ID, POLICY_ID, CHANGE_NO, STATUS, CHANGE_DATE
FROM mytable
MATCH_RECOGNIZE (
  PARTITION BY POLICY_ID
  ORDER BY CHANGE_DATE
  MEASURES MATCH_NUMBER() m,FIRST(R.ROW_ID) r
  ALL ROWS PER MATCH
  PATTERN (R+)
  DEFINE R AS STATUS=NEXT(STATUS)
) MR
WHERE ROW_ID = R
ORDER BY ROW_NUMBER() OVER(PARTITION BY POLICY_ID ORDER BY M DESC)
FETCH FIRST 1 ROW WITH TIES;

db <> fiddle demo


В качестве альтернативы:

SELECT *
FROM mytable 
MATCH_RECOGNIZE (
  PARTITION BY POLICY_ID
  ORDER BY CHANGE_DATE DESC
  MEASURES MATCH_NUMBER() m
           ,LAST(R.ROW_ID) ROW_ID
           ,LAST(R.STATUS) STATUS
           ,LAST(R.CHANGE_NO) CHANGE_NO
           ,LAST(R.CHANGE_DATE) CHANGE_DATE
  ONE ROW PER MATCH
  PATTERN (R+)
  DEFINE R AS STATUS=PREV(STATUS)
) MR
WHERE M = 1

дБ <> fiddle demo2

0 голосов
/ 25 декабря 2018

Хммм.,,

select t.*
from (select t.*,
             row_number() over (partition by policy_id order by change_date asc) as seqnum
      from t
      where not exists (select 1
                        from t t2
                        where t2.policy_id = t.policy_id and
                              t2.status <> t.status and
                              t2.change_date > t.change_date
                       )
     ) t
where seqnum = 1;

Внутренний подзапрос находит все строки, в которых - для данного номера политики - нет более поздней строки с другим статусом.Это определяет последнюю группу записей.

Затем она использует row_number() для перечисления строк.Эти внешние запросы выбирают первую строку для каждого policy_number.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...