我很难用语言表达这个问题,这可能就是为什么我找不到例子,所以这就是我想做的。
我有一张这样的桌子
| 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()
和累积 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
你应该计算一个新的组:
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 行受影响
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
柜台 |圣 |等 ------: | :------------------ | :------------------ 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
db<>小提琴这里
您可以使用排名功能
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
子句中使用它们。