查找同一系列中多次出现的最早和最晚日期

时间:2019-04-08 16:24:15

标签: sql oracle

我的第一个问题,我觉得我没有清楚解释,但是示例数据应该如此。

如何找到一个“类型”的最早日期早于另一“类型”的最早日期,说明不应该包含的“相同”类型的日期,然后为系列中的其他顺序日期确定相同的日期?

表格中的示例数据:

PERSON_ID  SERVICE_DATE SERVICE_TYPE
ABC        10/4/2018    INTAKE
ABC        10/8/2018    INTAKE
ABC        10/19/2018   DISCHARGE
ABC        10/25/2018   DISCHARGE
ABC        11/21/2018   INTAKE
ABC        12/3/2018    INTAKE
ABC        12/6/2018    INTAKE
ABC        12/26/2018   DISCHARGE

我想退货:

PERSON_ID  INTAKE_DATE DISCHARGE_DATE
ABC        10/4/2018   10/19/2018
ABC        11/21/2018  12/26/2018

编辑:第二个例子。如果进出日期在同一日期,我也想记录下来。

PERSON_ID  SERVICE_DATE  SERVICE_TYPE
DEF        10/1/2018     INTAKE
DEF        10/1/2018     DISCHARGE
DEF        11/5/2018     INTAKE
DEF        12/31/2018    DISCHARGE

我想退货:

PERSON_ID  INTAKE_DATE DISCHARGE_DATE
DEF        10/1/2018   10/1/2018
DEF        11/5/2018   12/31/2018

2 个答案:

答案 0 :(得分:2)

您可以使用MATCH_RECOGNIZE轻松匹配多行中的模式,如以下查询所示:

WITH test_vals AS (
    SELECT 'ABC' as PERSON_ID,TO_DATE('10/4/2018','mm/dd/yyyy') as SERVICE_DATE,'INTAKE' as SERVICE_TYPE FROM DUAL
    UNION SELECT 'ABC',TO_DATE('10/8/2018','mm/dd/yyyy'),'INTAKE' FROM DUAL
    UNION SELECT 'ABC',TO_DATE('10/19/2018','mm/dd/yyyy'),'DISCHARGE' FROM DUAL
    UNION SELECT 'ABC',TO_DATE('10/25/2018','mm/dd/yyyy'),'DISCHARGE' FROM DUAL
    UNION SELECT 'ABC',TO_DATE('11/21/2018','mm/dd/yyyy'),'INTAKE' FROM DUAL
    UNION SELECT 'ABC',TO_DATE('12/3/2018','mm/dd/yyyy'),'INTAKE' FROM DUAL
    UNION SELECT 'ABC',TO_DATE('12/6/2018','mm/dd/yyyy'),'INTAKE' FROM DUAL
    UNION SELECT 'ABC',TO_DATE('12/26/2018','mm/dd/yyyy'),'DISCHARGE' FROM DUAL
)

SELECT m.person_id,
       m.earliest_intake_date,
       m.earliest_discharge_date
FROM test_vals t
match_recognize (
    PARTITION BY person_id
    ORDER BY service_date, service_type DESC /* Order such that INTAKE comes before DISCHARGE if two items have the same service date */
    MEASURES
        MIN(service_date) AS earliest_intake_date,
        MAX(service_date) AS earliest_discharge_date
    ONE ROW PER match
    pattern (
        intake+ /* Match one or more INTAKE codes, followed by a DISCHARGE */
        discharge
    )
    define 
        intake AS service_type = 'INTAKE',
        discharge AS service_type = 'DISCHARGE'
) m

答案 1 :(得分:0)

,test_table为(   选择DUAL UNION ALL中的'ABC'PERSON_ID,to_date('10 / 04/2018','MM / DD / YYYY')SERVICE_DATE,'INTAKE'SERVICE_TYPE   选择DUAL UNION ALL中的'ABC'PERSON_ID,to_date('10 / 08/2018','MM / DD / YYYY')SERVICE_DATE,'INTAKE'SERVICE_TYPE   选择DUAL UNION ALL中的'ABC'PERSON_ID,to_date('10 / 19/2018','MM / DD / YYYY')SERVICE_DATE,'DISCHARGE'SERVICE_TYPE   选择DUAL UNION ALL中的'ABC'PERSON_ID,to_date('10 / 25/2018','MM / DD / YYYY')SERVICE_DATE,'DISCHARGE'SERVICE_TYPE   选择DUAL UNION ALL中的'ABC'PERSON_ID,to_date('11 / 21/2018','MM / DD / YYYY')SERVICE_DATE,'INTAKE'SERVICE_TYPE   从DUAL UNION ALL中选择“ ABC” PERSON_ID,to_date('12 / 03/2018','MM / DD / YYYY')SERVICE_DATE,'INTAKE'SERVICE_TYPE   选择DUAL UNION ALL中的'ABC'PERSON_ID,to_date('12 / 06/2018','MM / DD / YYYY')SERVICE_DATE,'INTAKE'SERVICE_TYPE   选择'ABC'PERSON_ID,to_date('12 / 26/2018','MM / DD / YYYY')SERVICE_DATE,'DISCHARGE'SERVICE_TYPE FROM DUAL ), 参数为(   SELECT T. ,行数rn   来自(     选择t1。,LAG(SERVICE_TYPE,1,'DISCHARGE')OVER(ORDER BY SERVICE_DATE)BEFORE_ROW     从test_table t1   )吨   哪里     T.SERVICE_TYPE ='INTAKE'并且     T.BEFORE_ROW ='DISCHARGE' ) 选择   tt1.person_id PERSON_ID,   tt1.service_date INTAKE,   (从TEST_TABLE T3的TEST.TABLE T3.SERVICE_TYPE ='DISCHARGE'中选择MAX(T3.SERVICE_DATE)并且(T3.SERVICE_DATE TT1.SERVICE_DATE ORDER BY tt1.SERVICE_DATE;