Oracle sql: поиск минимальных последовательных дат в пределах одной группы

Я знаю, что вопрос, вероятно, плохо объяснен, но я не знаю, как еще объяснить это. У меня есть следующие данные: (упорядочено по дате)

    DATE    GROUP
    11-Oct-16   A
    12-Oct-16   A
    13-Oct-16   A
    14-Oct-16   B
    15-Oct-16   B
    16-Oct-16   A
    17-Oct-16   A
    18-Oct-16   C
    19-Oct-16   C
    20-Oct-16   C
    21-Oct-16   C
    22-Oct-16   A
    23-Oct-16   A
    24-Oct-16   A

Я хочу найти последовательное использование для групп. Результаты, которые я хочу, объяснят это лучше меня:

    GROUP   MIN(DATE)   MAX(DATE)
    A   11-Oct-16   13-Oct-16
    B   14-Oct-16   15-Oct-16
    A   16-Oct-16   17-Oct-16
    C   18-Oct-16   21-Oct-16
    A   22-Oct-16   24-Oct-16

Любая идея, как это сделать в oracle sql? Спасибо.

sql,oracle,gaps-and-islands,

1

Ответов: 2


2

Это может быть способ:

with test("DATE","GROUP") as
(
    select to_date('11-10-16', 'dd-mm-rr'),'A' from dual union all
    select to_date('12-10-16', 'dd-mm-rr'),'A' from dual union all
    select to_date('13-10-16', 'dd-mm-rr'),'A' from dual union all
    select to_date('14-10-16', 'dd-mm-rr'),'B' from dual union all
    select to_date('15-10-16', 'dd-mm-rr'),'B' from dual union all
    select to_date('16-10-16', 'dd-mm-rr'),'A' from dual union all
    select to_date('17-10-16', 'dd-mm-rr'),'A' from dual union all
    select to_date('18-10-16', 'dd-mm-rr'),'C' from dual union all
    select to_date('19-10-16', 'dd-mm-rr'),'C' from dual union all
    select to_date('20-10-16', 'dd-mm-rr'),'C' from dual union all
    select to_date('21-10-16', 'dd-mm-rr'),'C' from dual union all
    select to_date('22-10-16', 'dd-mm-rr'),'A' from dual union all
    select to_date('23-10-16', 'dd-mm-rr'),'A' from dual union all
    select to_date('24-10-16', 'dd-mm-rr'),'A' from dual
)
select min("DATE"), max("DATE"), "GROUP" 
from (
        select "DATE",
               "DATE" - row_number() over (partition by "GROUP" order by "DATE") as minDate,
               "GROUP"
        from test
)
group by "GROUP", minDate
order by "GROUP", minDate

Внутренний запрос строит минимальную дату для группы последовательных дат, а внешняя - просто сводится к этой минимальной дате, тем самым создавая строку для каждой группы последовательных дат.

В стороне, лучше избегать использования зарезервированных слов в качестве имен столбцов.


0

Поэтому в основном я думаю, что правильный ответ был в комментарии @mathguy. Здесь я просто расширяюсь и предоставляю полный полный запрос.

select GROUP_NAME, grp_id, min(date_field) as starting_date, max(date_field) as ending_date
from (
select DATE_FIELD, GROUP_NAME, 
row_number() over ( order by date_field) - row_number() over ( partition by group_name order by date_field ) as grp_id
from darber.my_table) innested
group by GROUP_NAME, grp_id
order by min(date_field);

Обратите внимание: я изменил имя поля, потому что они давали конфликты в моей базе данных. В этом решении DATE теперь DATE_FIELD, а GROUP теперь GROUP_NAME.

Я нашел это очень умным и элегантным решением. Надеюсь, это поможет другим.

SQL, Oracle, пробелы и-острова,
Похожие вопросы