Как агрегировать / разбивать данные окна по динамической группе? - PullRequest
0 голосов
/ 13 мая 2018

Подобный вопрос, возможно, уже был задан и получен ответ, но у меня возникают проблемы с поиском чего-либо (сложно понять, что именно искать / как это сформулировать).

Если у меня есть таблица значений по дате:

select *
from (values
  (date '2018-05-11', 'lorem'),
  (date '2018-05-10', 'ipsum'),
  (date '2018-05-07', 'dolor'),
  (date '2018-05-05', 'hello'),
  (date '2018-05-04', 'world'),
  (date '2018-04-30', 'foo'),
  (date '2018-04-15', 'bar')
) as v(date, name)
order by date desc

Как можно агрегировать значения по группам дат (например, «5 дней») - динамически группировать по первому значению (например, 11–7 мая, 6–1, 30–26 апреля и т. Д.), не статически (например, по модулю 5 дней)?

Желаемый результат:

min_date   | max_date   | names
-----------+------------+--------------------
2018-05-07 | 2018-05-11 | lorem, ipsum, dolor
2018-05-04 | 2018-05-05 | hello, world
2018-04-30 | 2018-04-30 | foo
2018-04-15 | 2018-04-15 | bar

----

Полагаю, мне нужно сначала получить максимальную дату для группировки каждой строки, например: 2018-05-11, 2018-05-05 и т. Д.

Я пробовал два концептуальных подхода для этого, но ни один из них не работает.

---

Первый подход заключается в создании этой максимальной даты прокрутки, но это недопустимо (column "groupbydate" does not exist):

select *,
  case
    when date > (lag(groupByDate) over w) - interval '5 days' then (lag(groupByDate) over w)
    else date
  end as groupByDate
from input
window w as (order by date desc)

----

Второй подход - «найти» max / «group by» для каждой строки, но я не уверен, как отличить текущую таблицу строки date от текущей окно дата строки:

select *,
  max(date) filter (where date < input.date + interval '5 days') over w
from input
window w as (order by date desc)

Я думаю, что могу реализовать второй подход, используя подзапрос, но мне любопытно: возможно ли добиться этого с помощью оконных функций? Спасибо!

РЕДАКТИРОВАТЬ: Второй подход неверен. Он может найти другую дату "group by" для разных дат, которые должны быть в одной группе.

1 Ответ

0 голосов
/ 13 мая 2018

РЕДАКТИРОВАТЬ: На самом деле, это неправильно! Это может найти другую дату "group by" для разных дат, которые должны быть в одной группе.

Вот как я добился этого с помощью подзапроса:

select date, name, (
  select max(date)
  from input as i2
  where date < input.date + interval '5 days'
) as date_group
from input

И подключение к этому внешнему запросу дает мне желаемые результаты:

select min_date, max_date, names
from (
  select date_group, min(date) as min_date, max(date) as max_date, string_agg(name, ', ') as names
  from groups -- results of above query, e.g. using CTE
  group by date_group
  order by date_group desc
) as x

Все еще любопытно, есть ли способ сделать это с помощью оконных функций. Спасибо!

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