Как определить диапазоны дат / интервалы для указанных значений? - PullRequest
1 голос
/ 11 декабря 2019

У меня есть набор данных, который говорит мне owner для чего-то для каждого date, примеры данных ниже. В столбце date имеются некоторые разрывы.

|    owner    |    date     |
|-------------+-------------+
|  Samantha   |  2010-01-02 |
|  Max        |  2010-01-03 |
|  Max        |  2010-01-04 |
|  Max        |  2010-01-06 |
|  Max        |  2010-01-07 |
|  Conor      |  2010-01-08 |
|  Conor      |  2010-01-09 |
|  Conor      |  2010-01-10 |
|  Conor      |  2010-01-11 |
|  Abigail    |  2010-01-12 |
|  Abigail    |  2010-01-13 |
|  Abigail    |  2010-01-14 |
|  Abigail    |  2010-01-15 |
|  Max        |  2010-01-17 |
|  Max        |  2010-01-18 |
|  Abigail    |  2010-01-20 |
|  Conor      |  2010-01-21 |

Я пытаюсь написать запрос, который может захватывать диапазоны дат для каждого интервала времени owner's, например

|    owner    |    start   |     end    |
|-------------+------------+------------+
|  Samantha   | 2010-01-02 | 2010-01-02 |
|  Max        | 2010-01-03 | 2010-01-04 |
|  Max        | 2010-01-06 | 2010-01-07 |
|  Conor      | 2010-01-08 | 2010-01-11 |
|  Abigail    | 2010-01-12 | 2010-01-15 |
|  Max        | 2010-01-17 | 2010-01-18 |
|  Abigail    | 2010-01-20 | 2010-01-20 |
|  Conor      | 2010-01-21 | 2010-01-21 |

Я пытался думать об этом, используя min() и max(), но я застрял. Я чувствую, что мне нужно использовать lead() и lag(), но я не уверен, как их использовать, чтобы получить желаемый результат. Есть идеи? Заранее спасибо!

Ответы [ 2 ]

2 голосов
/ 11 декабря 2019

Это типичная проблема пробелов и островов. Вот один из способов решить эту проблему, используя row_number():

select owner, min(date) start, max(date) end
from (
    select 
        owner,
        row_number() over(order by date) rn1,
        row_number() over(partition by owner, order by date) rn2
    from mytable
) t
group by owner, rn1 - rn2

. Это работает путем ранжирования записей по date по двум различным разделам (внутри всей таблицы и внутри групп, имеющих одинаковые owner). Разница между рангами дает вам группу, к которой принадлежит каждая запись. Вы можете выполнить внутренний запрос и посмотреть на результаты, чтобы понять логику.

0 голосов
/ 12 декабря 2019

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

select owner, min(date), max(date)
from (select t.*,
             row_number() over (partition by owner order by date) as seqnum
      from t
     ) t
group by owner, (date - seqnum * interval '1 day')
order by min(date);

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

...