我必须为主页撰写正常运行时间报告。在可供我使用的表格中,我有2列。第一个是主页的状态(0表示离线,1表示在线),第二个表示此状态的持续时间(秒)。示例表可能如下所示:
-------------------------
| Status | Duration |
-------------------------
| 0 | 50 |
-------------------------
| 1 | 10 |
-------------------------
| 1 | 20 |
-------------------------
| 1 | 50 |
-------------------------
| 0 | 50 |
-------------------------
| 0 | 50 |
-------------------------
| 1 | 20 |
-------------------------
这在我的报告中看起来不太好,因为相同的stati应该聚合成一行而不是像这样显示为多行:
-------------------------
| Status | Duration |
-------------------------
| 0 | 50 |
-------------------------
| 1 | 80 |
-------------------------
| 0 | 100 |
-------------------------
| 1 | 20 |
-------------------------
有没有办法用PostgreSQL实现这个目标?
答案 0 :(得分:1)
正如我已经说过的那样,您需要一个id/datetime
列来跟踪进度。
只有这样,您才能在此方案中使用LEAD/LAG
函数或TABIBITOSAN方法。
PostgreSQL 9.6架构设置:
CREATE TABLE t
(id INT,Status int, Duration int)
;
INSERT INTO t
(id,Status, Duration)
VALUES
(1,0, 50),
(2,1, 10),
(3,1, 20),
(4,1, 50),
(5,0, 50),
(6,0, 50),
(7,1, 20)
;
查询1 :
SELECT STATUS
,Sum(duration)
FROM (
SELECT t.*
,row_number() OVER (
ORDER BY id
) - row_number() OVER (
PARTITION BY STATUS ORDER BY id
) AS seq
FROM t
) s
GROUP BY STATUS
,seq
ORDER BY max(id)
<强> Results 强>:
| status | sum |
|--------|-----|
| 0 | 50 |
| 1 | 80 |
| 0 | 100 |
| 1 | 20 |
答案 1 :(得分:0)
这种聚合可以通过使用窗口函数和分组来实现:
select max(status) status, sum(duration) duration from (
select status, duration, sum(case when status <> par then 1 else 0 end) over (order by id) wf from (
select id, status, duration, lag(status, 1) over () par from test
) a order by id
) a group by wf order by wf
您只需在窗口功能中正确设置排序。
测试数据:
create table test (status int, duration int, id bigserial primary key);
insert into test (status, duration) values (0, 50);
insert into test (status, duration) values (1, 10);
insert into test (status, duration) values (1, 20);
insert into test (status, duration) values (1, 50);
insert into test (status, duration) values (0, 50);
insert into test (status, duration) values (0, 50);
insert into test (status, duration) values (1, 20);
输出就像你想要的那样。