Я хочу сгруппировать интервал времени на основе данного допуска в postgres sql - PullRequest
0 голосов
/ 28 марта 2020
create table sample(id integer, name varchar(100), timeint time);

insert into sample values(1, 'aaa', '00:00:01');
insert into sample values(1, 'aaa', '00:00:01');
insert into sample values(1, 'aaa', '00:00:02');
insert into sample values(1, 'aaa', '00:00:03');
insert into sample values(1, 'aaa', '00:00:04');
insert into sample values(2, 'bbb', '00:00:01');
insert into sample values(2,'bbb', '00:00:02');
insert into sample values(2, 'bbb', '00:00:03');

select id,name,timeint,count(timeint) from sample
group by id,name,timeint;

------ вывод будет похож на ----

1   aaa 00:00:01    2
1   aaa 00:00:02    1
1   aaa 00:00:03    1
1   aaa 00:00:04    1
2   bbb 00:00:01    1
2   bbb 00:00:02    1
2   bbb 00:00:03    1

Таким образом, вышеприведенный вывод должен быть перегруппирован таким образом, чтобы для того же идентификатора и имени, timeint с 1 se c допуск следует считать одинаковым

______ ожидаемый результат _________________

1   aaa 00:00:01    3
1   aaa 00:00:03    2
2   bbb 00:00:01    2
2   bbb 00:00:03    1 

Ответы [ 2 ]

0 голосов
/ 28 марта 2020

Для этого примера данных вы можете применить лог c, чтобы все timeint с четным числом секунд были сгруппированы с предыдущими timeint (-1 секунда):

select 
  id, 
  name, 
  timeint - interval '1 seconds' * (mod(extract(second from timeint)::int, 2) = 0)::int  time_int, 
  count(*) counter
from sample
group by id, name, time_int
order by id, name, time_int

Смотрите демо . Результаты:

| id  | name | time_int | counter |
| --- | ---- | -------- | ------- |
| 1   | aaa  | 00:00:01 | 3       |
| 1   | aaa  | 00:00:03 | 2       |
| 2   | bbb  | 00:00:01 | 2       |
| 2   | bbb  | 00:00:03 | 1       |
0 голосов
/ 28 марта 2020

Общее решение вашей проблемы требует рекурсивного CTE. Если все времена с точностью до одной секунды и вам нужны только две секунды, возможно, существует способ обойти это.

Однако в этом решении используется рекурсивный CTE:

with recursive s as (
      select s.id, s.name, s.timeint, count(*) as cnt,
             row_number() over (partition by id order by timeint) as seqnum
      from sample s
      group by s.id, s.name, s.timeint
     ),
     cte as (
      select id, timeint, name, seqnum, timeint as start_timeint, cnt
      from s
      where seqnum = 1
      union all
      select s.id, s.timeint, s.name, s.seqnum,
             (case when s.timeint <= cte.start_timeint + interval '1 second'
                   then cte.start_timeint else s.timeint
              end),
             s.cnt
      from cte join
           s
           on s.id = cte.id and s.seqnum = cte.seqnum + 1
     )
select  id, name, start_timeint, sum(cnt)
from cte
group by id, name, start_timeint
order by id, start_timeint;

Здесь - это дБ <> скрипка.

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