LEAD & LAG analytic function
Example of LEAD and LAG analytic functions used to determine previous and next records
INSERT /*+ append */ INTO STG.REHAB_GET_END_DATES SELECT PAYMENT_CLASSIFICATION_NUMBER, CLAIM_WCA_ID, PAYMENT_ITEM_AMT, SERVICE_DATE_ID, LAG_SERVICE, DAYS_SINCE, RNUM ,CASE WHEN PAYMENT_CLASSIFICATION_NUMBER IN ('OR0104') THEN LEAD(PAYMENT_CLASSIFICATION_NUMBER) OVER (PARTITION BY CLAIM_WCA_ID, SERVICE_PROVIDER_ID ORDER BY CLAIM_WCA_ID, SERVICE_DATE_ID ASC) END LEAD_PAY_CLSS --payment class of next service chronolgically ,CASE WHEN PAYMENT_CLASSIFICATION_NUMBER IN ('OR0104') THEN LEAD(PAYMENT_ITEM_AMT) OVER (PARTITION BY CLAIM_WCA_ID, SERVICE_PROVIDER_ID ORDER BY CLAIM_WCA_ID, SERVICE_DATE_ID ASC) END LEAD_PAY_AMT --payment amount of next service chronolgically ,CASE WHEN PAYMENT_CLASSIFICATION_NUMBER IN ('OR0104') THEN LEAD(DAYS_SINCE) OVER (PARTITION BY CLAIM_WCA_ID, SERVICE_PROVIDER_ID ORDER BY CLAIM_WCA_ID, SERVICE_DATE_ID ASC) END LEAD_DAYS_SINCE --number of days between this service and next service chronolgically ,CASE WHEN LEAD(DAYS_SINCE) OVER (PARTITION BY CLAIM_WCA_ID, SERVICE_PROVIDER_ID ORDER BY CLAIM_WCA_ID, SERVICE_DATE_ID ASC) >= 90 THEN SERVICE_DATE_ID ELSE NULL END CASE_END_DATE_ID --if next service date >= 90 days then this is the end date of this case ,SERVICE_PROVIDER_ID ,AGENT_INSURER_ID ,WORK_STATUS_ID ,RTW_OUTCOME_FG ,DIFF_EMP_FG ,CASE WHEN RNUM = 1 THEN SERVICE_DATE_ID WHEN DAYS_SINCE >= 90 THEN SERVICE_DATE_ID ELSE NULL --if days between this service and previous service >=90 then this is a new service hence the service date is the start date of a new case END CASE_START_DATE_ID FROM (--as inner plus calculates days between this and previous service SELECT PAYMENT_CLASSIFICATION_NUMBER, CLAIM_WCA_ID, PAYMENT_ITEM_AMT, SERVICE_DATE_ID, LAG_SERVICE, NVL(TO_DATE(SERVICE_DATE_ID,'YYYYMMDD') - LAG_SERVICE,0) DAYS_SINCE, RNUM, SERVICE_PROVIDER_ID, AGENT_INSURER_ID, WORK_STATUS_ID, RTW_OUTCOME_FG, DIFF_EMP_FG FROM (-- as inner plus notes the date of previous service SELECT PAYMENT_CLASSIFICATION_NUMBER, CLAIM_WCA_ID, PAYMENT_ITEM_AMT, SERVICE_DATE_ID, RNUM, LAG(TO_DATE(SERVICE_DATE_ID,'YYYYMMDD')) OVER (PARTITION BY CLAIM_WCA_ID, SERVICE_PROVIDER_ID ORDER BY CLAIM_WCA_ID, SERVICE_DATE_ID ASC) LAG_SERVICE, --gets the previous service SERVICE_PROVIDER_ID, AGENT_INSURER_ID, WORK_STATUS_ID, RTW_OUTCOME_FG, DIFF_EMP_FG FROM (--sums of payments by PCC group and numbered list of txns earliest to latest (this over last 13 quarters) SELECT PAYMENT_CLASSIFICATION_NUMBER, CLAIM_WCA_ID, SUM(PAYMENT_ITEM_AMT) PAYMENT_ITEM_AMT, --sum amounts on the PCC groups SERVICE_DATE_ID, ROW_NUMBER() OVER (PARTITION BY CLAIM_WCA_ID, SERVICE_PROVIDER_ID ORDER BY CLAIM_WCA_ID, SERVICE_DATE_ID ASC) RNUM, --order and number claims by SP, ascending, earliers is 1 SERVICE_PROVIDER_ID, AGENT_INSURER_ID, WORK_STATUS_ID, RTW_OUTCOME_FG, CASE WHEN INSTR((LISTAGG(DIFF_EMP_FG,'') WITHIN GROUP (ORDER BY SERVICE_DATE_ID)),'Y',1,1) > 0 THEN 'Y' ELSE 'N' END DIFF_EMP_FG --not sure what this means or is for... FROM (--group PCC into 2 groups, looking back for service dates in the last 13 quarters SELECT CASE WHEN DPC.PAYMENT_CLASSIFICATION_NUMBER IN ('OR01', 'OR04') THEN 'OR0104' WHEN DPC.PAYMENT_CLASSIFICATION_NUMBER IN ('OR02', 'OR03') THEN 'OR0203' END PAYMENT_CLASSIFICATION_NUMBER, S.CLAIM_WCA_ID, S.PAYMENT_ITEM_AMT, S.SERVICE_DATE_ID, S.SERVICE_PROVIDER_ID, S.AGENT_INSURER_ID, S.WORK_STATUS_ID, S.RTW_OUTCOME_FG ,CASE WHEN DPC.PAYMENT_CLASSIFICATION_NUMBER = 'OR02' THEN 'N' WHEN DPC.PAYMENT_CLASSIFICATION_NUMBER = 'OR03' THEN 'Y' ELSE 'N' END DIFF_EMP_FG FROM BID.S_CLAIM_PAYMENT_BY_SERVICE S, BID.D_SERVICE_TYPE D, BID.D_PAYMENT_CLASSIFICATION DPC WHERE S.SERVICE_TYPE_ID = D.SERVICE_TYPE_ID AND S.PAYMENT_CLASSIFICATION_ID = DPC.PAYMENT_CLASSIFICATION_ID AND D.SERVICE_TYPE_CODE = 'OR' --AND S.SERVICE_DATE_ID > (SELECT TO_NUMBER(TO_CHAR(ADD_MONTHS(MAX(LAST_COMPLETE_MONTH), -24),'YYYYMMDD')) FROM BID.SNAPSHOT_CONTROL) -- limit data retention to 24 months --AND S.AGENT_INSURER_ID = 5 --AND S.CLAIM_WCA_ID IN (8092666) AND DPC.PAYMENT_CLASSIFICATION_NUMBER IN ('OR01', 'OR04', 'OR02', 'OR03') AND S.SERVICE_DATE_ID BETWEEN v_qtr1_start_date and v_qtr1_end_date ) WHERE SERVICE_DATE_ID NOT IN (0, -1) --ignore blank service dates GROUP BY PAYMENT_CLASSIFICATION_NUMBER, CLAIM_WCA_ID, SERVICE_DATE_ID, SERVICE_PROVIDER_ID, AGENT_INSURER_ID, WORK_STATUS_ID, RTW_OUTCOME_FG ) ) ); COMMIT;