Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select the first record of the last group when there are repeating groups

Trying to select the first record of the latest repeating STATUS groups for each POLICY_ID. How can I do this?

Edit/Note: There can be more than two status repetitions as shown in the last three rows.

View of the data:

enter image description here

Desired output:

enter image description here

SQL for data:

--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;
like image 682
kzmlbyrk Avatar asked Dec 25 '18 20:12

kzmlbyrk


1 Answers

Hmmm . . .

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;

The inner subquery finds all rows where -- for a given policy number -- there is no later row with a different status. That defines the last group of records.

It then uses row_number() to enumerate the rows. These outer query selects the first row for each policy_number.

like image 73
Gordon Linoff Avatar answered Oct 21 '22 06:10

Gordon Linoff