Sql 如何检索共享相同状态的连续记录的最大日期间隔?
我正在使用PostgreSQL 9.4 给定一个带有时间戳和读取状态布尔标志的表:Sql 如何检索共享相同状态的连续记录的最大日期间隔?,sql,postgresql,group-by,Sql,Postgresql,Group By,我正在使用PostgreSQL 9.4 给定一个带有时间戳和读取状态布尔标志的表: CREATE TABLE status ( id serial NOT NULL, created timestamp with time zone NOT NULL, read boolean NOT NULL, CONSTRAINT status_pkey PRIMARY KEY (id), CONSTRAINT status_unique_created_read
CREATE TABLE status (
id serial NOT NULL,
created timestamp with time zone NOT NULL,
read boolean NOT NULL,
CONSTRAINT status_pkey PRIMARY KEY (id),
CONSTRAINT status_unique_created_read UNIQUE(created, read)
);
我想检索共享相同状态的连续记录的最大间隔。读取标志的每次更改都应启动另一组记录
最终目标是获得共享读取状态的创建日期的最大间隔为True
例如,让我们用以下记录填充表:
INSERT INTO status (created, read) VALUES ('2016-02-23 14:53:39.668225-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-24 09:00:07.384002-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-26 19:33:00.677397-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-26 19:58:07.070881-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-28 09:00:47.831193-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-28 09:00:50.632217-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-28 09:00:50.655375-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-28 09:00:54.146508-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-28 09:00:56.524389-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-28 09:00:58.828541-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-28 09:01:00.809748-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-28 09:01:03.14392-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-28 09:01:05.506604-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-28 09:01:07.606256-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-28 09:01:09.986617-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-28 09:01:12.275312-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-28 09:01:14.194565-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-28 09:01:16.429208-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-28 09:01:18.657266-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-28 09:01:20.877406-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-28 09:01:23.122152-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-29 10:37:25.036703-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-29 11:07:10.564814-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-29 11:47:38.78204-03', false);
INSERT INTO status (created, read) VALUES ('2016-02-29 11:56:49.895785-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-29 12:46:07.906734-03', false);
INSERT INTO status (created, read) VALUES ('2016-02-29 17:19:09.776746-03', true);
INSERT INTO status (created, read) VALUES ('2016-02-29 17:24:07.145661-03', false);
INSERT INTO status (created, read) VALUES ('2016-02-29 21:11:02.558749-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-01 09:00:00.871397-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-01 10:46:17.66168-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-01 14:12:43.717506-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-02 09:00:04.303278-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-02 17:33:16.196374-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-02 17:36:29.84208-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-03 09:00:01.929879-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-03 09:00:01.940345-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-04 09:00:03.120712-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-04 10:59:01.651798-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-04 17:06:27.565846-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-04 17:07:00.258593-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-04 17:30:23.126116-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-04 17:43:41.512822-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-05 09:00:13.42016-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-06 09:00:05.610203-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-07 16:33:58.102805-03', false);
INSERT INTO status (created, read) VALUES ('2016-03-07 16:53:48.820488-03', false);
INSERT INTO status (created, read) VALUES ('2016-03-07 18:51:44.182288-03', false);
INSERT INTO status (created, read) VALUES ('2016-03-09 09:00:04.369842-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-09 09:00:04.380432-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-09 09:00:04.450373-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-09 09:00:04.598239-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-09 09:00:04.7075-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-10 09:00:00.923048-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-11 09:00:01.02605-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-11 16:34:43.341189-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-11 18:39:02.517519-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-11 18:39:02.535953-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-15 09:00:01.405166-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-15 12:08:51.729326-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-16 09:00:01.594785-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-17 09:00:01.189489-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-18 09:00:01.105867-03', true);
INSERT INTO status (created, read) VALUES ('2016-03-18 15:32:03.153641-03', false);
INSERT INTO status (created, read) VALUES ('2016-03-21 10:21:18.110903-03', false);
INSERT INTO status (created, read) VALUES ('2016-03-22 10:34:29.630107-03', false);
分组数据可能如下所示:
min_created;max_created;read;count
"2016-02-23 14:53:39.668225-03";"2016-02-29 11:07:10.564814-03";TRUE;23
"2016-02-29 11:47:38.78204-03";"2016-02-29 11:47:38.78204-03";FALSE;1
"2016-02-29 11:56:49.895785-03";"2016-02-29 11:56:49.895785-03";TRUE;1
"2016-02-29 12:46:07.906734-03";"2016-02-29 12:46:07.906734-03";FALSE;1
"2016-02-29 17:19:09.776746-03";"2016-02-29 17:19:09.776746-03";TRUE;1
"2016-02-29 17:24:07.145661-03";"2016-02-29 17:24:07.145661-03";FALSE;1
"2016-02-29 21:11:02.558749-03";"2016-03-06 09:00:05.610203-03";TRUE;17
"2016-03-07 16:33:58.102805-03";"2016-03-07 18:51:44.182288-03";FALSE;3
"2016-03-09 09:00:04.369842-03";"2016-03-18 09:00:01.105867-03";TRUE;15
"2016-03-18 15:32:03.153641-03";"2016-03-22 10:34:29.630107-03";FALSE;3
对于读取状态之间的最大日期间隔应该是:
"2016-03-09 09:00:04.369842-03";"2016-03-18 09:00:01.105867-03"
如何使用SQL获得此结果?以下查询将为每个状态生成所有间隔组
select
nn.created,
(
select
(
select
nn2.created
from
status nn2
where
nn2.created < nn1.created
and
nn2.read = nn.read
order by
1 desc
limit 1
)
from
status nn1
where
nn1.created > nn.created
and
nn1.read <> nn.read
order by
1
limit 1
) as modified,
nn.read
from
status nn
order by
nn.created
这里有另一个解决方案也适用于其他db引擎
SELECT min(created), Max(created), read, Count(1)
FROM (
SELECT created, read
, (SELECT Max(created) FROM status WHERE created < t.created AND read <> t.read) x1
, (SELECT Min(created) FROM status WHERE created > t.created AND read <> t.read) x2
FROM status t)
GROUP BY read, x1, x2
ORDER BY 1
谢谢我来测试你的答案。很好!这比第一个答案还要快。谢谢若你们需要提高你们的查询速度,你们可以在创建的表上添加索引,读到你们的表中谢谢!我已经更新了这个问题,包括一个id字段和索引。我注意到您在子查询中使用了mincreated和maxcreated来标识组。用minid和maxid替换它同样有效。
SELECT min(created), Max(created), read, Count(1)
FROM (
SELECT created, read
, (SELECT Max(created) FROM status WHERE created < t.created AND read <> t.read) x1
, (SELECT Min(created) FROM status WHERE created > t.created AND read <> t.read) x2
FROM status t)
GROUP BY read, x1, x2
ORDER BY 1