Using LEAD and LAG with an unknown number of rows

DJC :

I have a table with information about service involvement for a group of people as in the code below, which I am running in Oracle.

CREATE TABLE SRVC_EPISODES
(
   CASE_INDEX        NUMBER (10),
   CLIENT_ID         NUMBER (10),
   SRVC_ID           NUMBER (10),
   SRVC_START_DT     DATE,
   SRVC_END_DT       DATE,
   SRVC_END_REASON   VARCHAR2 (70 BYTE)
);

INSERT INTO SRVC_EPISODES VALUES (1, 1, 3747, TO_DATE('03/28/2017', 'mm/dd/yyyy'), TO_DATE('06/27/2017', 'mm/dd/yyyy'), 'Full Completion');
INSERT INTO SRVC_EPISODES VALUES (2, 1, 5231, TO_DATE('02/16/2018', 'mm/dd/yyyy'), TO_DATE('06/30/2018', 'mm/dd/yyyy'), 'Service Transfer');
INSERT INTO SRVC_EPISODES VALUES (3, 1, 3929, TO_DATE('07/01/2018', 'mm/dd/yyyy'), TO_DATE('07/01/2018', 'mm/dd/yyyy'), 'Service Transfer');
INSERT INTO SRVC_EPISODES VALUES (4, 1, 6688, TO_DATE('07/13/2018', 'mm/dd/yyyy'), TO_DATE('10/19/2018', 'mm/dd/yyyy'), 'Full Completion');
INSERT INTO SRVC_EPISODES VALUES (5, 2, 73, TO_DATE('10/03/2017', 'mm/dd/yyyy'), TO_DATE('06/30/2018', 'mm/dd/yyyy'), 'Service Transfer');
INSERT INTO SRVC_EPISODES VALUES (6, 2, 201, TO_DATE('05/07/2018', 'mm/dd/yyyy'), TO_DATE('06/30/2018', 'mm/dd/yyyy'), 'Service Transfer');
INSERT INTO SRVC_EPISODES VALUES (7, 2, 8102, TO_DATE('06/02/2018', 'mm/dd/yyyy'), TO_DATE('06/30/2018', 'mm/dd/yyyy'), 'Service Transfer');
INSERT INTO SRVC_EPISODES VALUES (8, 2, 4164, TO_DATE('07/01/2018', 'mm/dd/yyyy'), TO_DATE('03/20/2019', 'mm/dd/yyyy'), 'Incomplete');
INSERT INTO SRVC_EPISODES VALUES (9, 2, 2066, TO_DATE('07/01/2018', 'mm/dd/yyyy'), TO_DATE('12/02/2019', 'mm/dd/yyyy'), 'Failed Classes');

An issue that I am encountering is that often times, an individual will transfer providers mid-way through their service, as indicated by differing SRVC_IDs and the preceding SRVC_END_REASON, when sorting by CLIENT_ID --> SRVC_START_DT --> SRVC_END_DT.

In the example below, CLIENT_ID #1 has two distinct service episodes - one which took place from 3/28/2017 - 6/27/2017 which they successfully completed. Their next service however, took place with three different providers (three distinct service IDs), and took place from 2/16/2018 to 10/19/2018, which they also successfully completed.

CLIENT_ID #4 also has two distinct service episodes. The first took place from 10/3/2017 and ended on 3/20/2019 with an incomplete. Their next service episode took place from 7/1/2018 to 12/2/2019, which they failed. Even though this might be hard to see, CASE_INDEX #9 is a different service as the preceding service did not have 'transfer' as a service end reason (grouped by CLIENT_ID, then sorted by SRVC_START_DT, then SRVC_END_DT).

I'd say the biggest issue that I am running into is that the number of transfers for each client is not fixed, if they have any transfers at all. If we need to, lets assume that maximum number of transfers would be 5.

I know that the solution to this involves using lead/lag, but I after much struggle I can't figure out how. My end goal is to have correct SRVC_START_DT, SRVC_END_DT, and SRVC_END_REASON as in the example below.

Data Example

Tony Andrews :

This seems to do it (along with a couple of extra columns you can dispense with):

select v2.*
,      min(srvc_start_dt) over (partition by grp order by srvc_start_dt) new_start_dt
,      max(srvc_end_dt)    over (partition by grp order by srvc_start_dt desc) new_end_dt
,      first_value(srvc_end_reason) over (partition by grp order by srvc_start_dt desc) new_end_reason
from (
  select v.*
  ,     sum(stat) over(order by client_id desc, srvc_start_dt desc, srvc_end_dt desc) grp 
  from (
    select s.*
    ,      case when srvc_end_reason not like '%Transfer%' then 1 end as stat
    from   SRVC_EPISODES s
  ) v
) v2
order by 1;

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=397875&siteId=1