Sql 按重复的列分组

Sql 按重复的列分组,sql,postgresql,Sql,Postgresql,我很难把这个问题用语言表达出来,这可能就是为什么我找不到一个例子的原因,下面是我想做的 我有一张这样的桌子 | 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

我很难把这个问题用语言表达出来,这可能就是为什么我找不到一个例子的原因,下面是我想做的

我有一张这样的桌子

    | 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 |

因此,我想知道如何在不使用嵌套查询的情况下理想地结合分组和分区,您必须使用相同的计数器重复值来指定组。这可以使用两个窗口函数lag和CUMMARY sum来完成:


您应该计算一个新的组:

dbfiddle

您可以使用排名功能


这将使用两个排序函数Seq1-Seq2的差异,并在GROUP BY子句中使用它们。

我在这里没有看到问题。更新以澄清@STLDeveloper
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
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
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);