Поиск самой ранней и последней даты в диапазоне для нескольких вхождений в одной серии - PullRequest
1 голос
/ 08 апреля 2019

Мой первый вопрос, и я чувствую, что не объясняю его четко, но пример данных должен.

Как найти самую раннюю дату для одного "типа" перед самой ранней датой другого "типа"с учетом дат «того же» типа, которые не должны быть включены, то же самое для дополнительных последовательных дат в серии?

Пример данных в таблице:

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 ]

2 голосов
/ 08 апреля 2019

Вы можете использовать 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
0 голосов
/ 09 апреля 2019

с test_table as (выберите 'ABC' PERSON_ID, to_date ('10 / 04/2018 ',' MM / DD / YYYY ') SERVICE_DATE,' INTAKE 'SERVICE_TYPE FRU DUAL UNION ALL выберите' ABC 'PERSON_ID, to_date ('10/08/2018 ',' MM / DD / YYYY ') SERVICE_DATE,' INTAKE 'SERVICE_TYPE ИЗ ДВОЙНОГО СОЮЗА ВСЕ выберите' ABC 'PERSON_ID, to_date ('10 / 19/2018', 'MM / DD / YYYY') SERVICE_DATE, 'DISCHARGE' SERVICE_TYPE ИЗ ДВОЙНОГО СОЮЗА ВСЕ выберите 'ABC' PERSON_ID, to_date ('10 / 25/2018 ',' MM / DD / YYYY ') SERVICE_DATE,' DISCHARGE 'SERVICE_TYPE ИЗ ДВОЙНОГО СОЮЗА ALL ALL выберите' ABC 'PERSON_ID, to_date('11 / 21/2018 ',' MM / DD / YYYY ') SERVICE_DATE,' INTAKE 'SERVICE_TYPE FROM DUAL UNION ALL выберите' ABC 'PERSON_ID, to_date ('12 / 03/2018', 'MM / DD / YYYY') SERVICE_DATE, 'INTAKE' SERVICE_TYPE ИЗ ДВОЙНОГО СОЮЗА ВСЕ выберите '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 FRU DUAL), в качестве параметра (SELECT T. , rownum rn FROM(выберите t1. , LAG (SERVICE_TYPE, 1, 'DISCHARGE') OVER (ORDER BY SERVICE_DATE) BEFORE_ROW из test_table t1) t, где T.SERVICE_TYPE = 'INTAKE' И T.BEFORE_ROW = 'DISCHARGE') выберите tt1.person_id PERSON_ID, tt1.service_date INTAKE, (ВЫБЕРИТЕ МАКС. (T3.SERVICE_DATE) ОТ TEST_TABLE T3, ГДЕ T3.SERVICE_TYPE = 'DISCHARGE' И (T3.SERVICE_DATE TT1.SERVICE_DATE ORDER BY tt1.SERVICE_DATE;

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