Сгруппировать по столбцу, который повторяется - PullRequest
0 голосов
/ 24 апреля 2018

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

У меня есть стол, как такой

    | counter|      timestamp      |
    |   1    | 2018-01-01T11:11:01 |
    |   1    | 2018-01-01T11:11:02 |
    |   1    | 2018-01-01T11:11:03 |
    |   2    | 2018-01-01T11:11:04 |
    |   2    | 2018-01-01T11:11:05 |
    |   3    | 2018-01-01T11:11:06 |
    |   3    | 2018-01-01T11:11:07 |
    |   1    | 2018-01-01T11:11:08 |
    |   1    | 2018-01-01T11:11:09 |
    |   1    | 2018-01-01T11:11:10 |

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

SELECT counter, MAX(timestamp) as st, MIN(timestamp) as et 
FROM table 
GROUP BY counter;

результат будет

    | counter |          st         |         et          |
    |   1     | 2018-01-01T11:11:01 | 2018-01-01T11:11:03 |
    |   2     | 2018-01-01T11:11:04 | 2018-01-01T11:11:05 |
    |   3     | 2018-01-01T11:11:06 | 2018-01-01T11:11:07 |
    |   1     | 2018-01-01T11:11:08 | 2018-01-01T11:11:10 |

вместо того, что на самом деле происходит, что является

    | counter |          st         |         et          |
    |   1     | 2018-01-01T11:11:01 | 2018-01-01T11:11:10 |
    |   2     | 2018-01-01T11:11:04 | 2018-01-01T11:11:05 |
    |   3     | 2018-01-01T11:11:06 | 2018-01-01T11:11:07 |

Так что я хотел бы кое-что, что идеально для объединения групп и разделов без вложенных запросов

Ответы [ 3 ]

0 голосов
/ 24 апреля 2018

Вы должны рассчитать новые группы:

create table tbl(counter int, ts timestamp);
insert into tbl values
    (1, '2018-01-01T11:11:01'),
    (1, '2018-01-01T11:11:02'),
    (1, '2018-01-01T11:11:03'),
    (2, '2018-01-01T11:11:04'),
    (2, '2018-01-01T11:11:05'),
    (3, '2018-01-01T11:11:06'),
    (3, '2018-01-01T11:11:07'),
    (1, '2018-01-01T11:11:08'),
    (1, '2018-01-01T11:11:09'),
    (1, '2018-01-01T11:11:10');
✓

10 rows affected
select min(counter) as counter, min(ts) as st, max(ts) as et
from
(
    select counter, ts, sum(rst) over (order by ts) as grp
    from 
         (
         select counter, ts,
                case when coalesce(lag(counter) over (order by ts), -1) <> counter then 1 end rst
         from   tbl
         ) t1
) t2
group by grp
counter | st                  | et                 
------: | :------------------ | :------------------
      3 | 2018-01-01 11:11:06 | 2018-01-01 11:11:07
      1 | 2018-01-01 11:11:08 | 2018-01-01 11:11:10
      2 | 2018-01-01 11:11:04 | 2018-01-01 11:11:05
      1 | 2018-01-01 11:11:01 | 2018-01-01 11:11:03

дБ <> Fiddle здесь

0 голосов
/ 25 апреля 2018

Вы можете использовать ранжирование функция

select counter, min(timestamp) st, max(timestamp) et
from (select *, 
               row_number() over (order by timestamp) Seq1,
               row_number() over (partition by counter order by timestamp) Seq2 
      from table 
     ) t
group by counter, (Seq1-Seq2);

Это будет использовать различия двух функций ранжирования (Seq1-Seq2) и использовать их в предложении GROUP BY.

0 голосов
/ 24 апреля 2018

Вы должны назначить группы с одинаковыми повторяющимися значениями счетчика.Это можно сделать с помощью двух оконных функций lag() и совокупной sum():

select counter, min(timestamp) as st, max(timestamp) as et
from (
    select counter, timestamp, sum(grp) over w as grp
    from (
        select *, (lag(counter, 1, 0) over w <> counter)::int as grp
        from my_table
        window w as (order by timestamp)
        ) s
    window w as (order by timestamp)
    ) s
group by counter, grp
order by st

DbFiddle.

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