Группировка по 7-дневному интервалу postgresql - PullRequest
1 голос
/ 22 сентября 2019

Я знаю, что это распространенный вопрос, но я не смог найти то, что соответствует моему случаю.У меня есть эти данные:

  id |    obs     
----+------------
  1 | 2018-01-01
  2 | 2018-01-02
  3 | 2018-01-03
  4 | 2018-01-04
  5 | 2018-01-05
  6 | 2018-01-06
  7 | 2018-01-07
  8 | 2018-01-15
  9 | 2018-01-20
 10 | 2018-02-03
 11 | 2018-02-04
 12 | 2018-02-05
 13 | 2018-02-06
 14 | 2018-02-06

Я хочу, чтобы эти данные были сгруппированы на основе 7-дневного интервала.То есть группы будут:

  • Группа 1: идентификатор от 1 до 7
  • Группа 2: идентификатор 8 и 9
  • Группа 3: идентификатор от 10 до 14

Как этот запрос в PostgreSQL?

Заранее спасибо

Ответы [ 2 ]

2 голосов
/ 22 сентября 2019

Если вы хотите сгруппировать вещи на основе разрыва семи дней, используйте lag() и совокупную сумму для определения групп:

select t.*,
       count(*) filter (where prev_obs is null or prev_obs < obs - interval '7 day') over (order by obs) as grp
from (select t.*,
             lag(obs) over (order by obs) as prev_obs
      from t
     ) t
2 голосов
/ 22 сентября 2019

Я бы поступил следующим образом:

  • сначала используйте подзапрос, чтобы сравнить дату текущей записи с минимальной датой серии;разница в днях между датами, разделенными на 7, дает вам первую версию группы, к которой принадлежит запись (но на данный момент номера групп не обязательно являются последовательными)
  • затем используйте DENSE_RANK() во внешнем запросе дляпереназначить номера групп как последовательные номера:

Запрос:

SELECT 
    id,
    obs,
    DENSE_RANK() OVER(ORDER BY gr) grp
FROM (
    SELECT 
        id,
        obs,
        MIN(obs) OVER(),
        (obs - MIN(obs) OVER())::int/7 + 1 gr
    FROM mytable
) x
ODER BY id

Демонстрация на DB Fiddle ;

| id  | obs                      | grp |
| --- | ------------------------ | --- |
| 1   | 2018-01-01T00:00:00.000Z | 1   |
| 2   | 2018-01-02T00:00:00.000Z | 1   |
| 3   | 2018-01-03T00:00:00.000Z | 1   |
| 4   | 2018-01-04T00:00:00.000Z | 1   |
| 5   | 2018-01-05T00:00:00.000Z | 1   |
| 6   | 2018-01-06T00:00:00.000Z | 1   |
| 7   | 2018-01-07T00:00:00.000Z | 1   |
| 8   | 2018-01-15T00:00:00.000Z | 2   |
| 9   | 2018-01-20T00:00:00.000Z | 2   |
| 10  | 2018-02-03T00:00:00.000Z | 3   |
| 11  | 2018-02-04T00:00:00.000Z | 3   |
| 12  | 2018-02-05T00:00:00.000Z | 4   |
| 13  | 2018-02-06T00:00:00.000Z | 4   |
| 14  | 2018-02-06T00:00:00.000Z | 4   |
...