Sql 获取停止(第x行)和开始(第x行)之间的时间间隔

Sql 获取停止(第x行)和开始(第x行)之间的时间间隔,sql,postgresql,intervals,postgresql-9.5,sql-timestamp,Sql,Postgresql,Intervals,Postgresql 9.5,Sql Timestamp,我在PostgreSQL 9.5中有一个表,每行有两个时间戳,timestampstart和timestampstop CREATE TABLE routes( ID serial PRIMARY KEY, TIMESTAMPSTART timestamp default NULL, TIMESTAMPEND timestamp default NULL ); 现在我不想计算开始和停止之间的间隔,而是计算停止和下一次开始之间的间隔。因此,我需要第x行的timestamp

我在PostgreSQL 9.5中有一个表,每行有两个时间戳,
timestampstart
timestampstop

CREATE TABLE routes(
    ID serial PRIMARY KEY,
    TIMESTAMPSTART timestamp default NULL,
    TIMESTAMPEND timestamp default NULL
);
现在我不想计算开始和停止之间的间隔,而是计算停止和下一次开始之间的间隔。因此,我需要第x行的
timestamp stop
和第x+1行的
timestamp start
之间的间隔。顺便说一下,
ID
不是按时间顺序排列的

您不能只使用简单值,因为您需要两个不同列之间的间隔

可以使用添加谓词的各种连接变体。带索引的
timestampstart
a
LATERAL
join with
LIMIT 1
可能是最快的

假设
timestampstart
唯一的
,否则需要定义如何断开连接。
UNIQUE
约束还将提供性能所需的索引:


如果“事件”之间没有重叠,那么您可以执行一个简单的窗口函数。查询可以简单到:

SELECT id, lead(timestampstart) OVER (ORDER BY timestampstart) -
           timestampend AS timetonext
FROM routes;


此解决方案比以下解决方案快一个数量级:

如果没有“下一行”,应该发生什么?如果存在重复的值怎么办?Order by
ID
除了时间戳之外?如果有一个适当的查询,这个查询将是等效的,并且更简单、更快。一个角落大小写的区别是:我的查询假设
timestampstart>r.timestampend
,同时也允许相等:
timestampstart>=r.timestampend
。范围类型(或SQL
OVERLAPS
运算符)默认情况下将上限视为独占的,下一个间隔可以从与上一个间隔结束时相同的时间戳开始,并且不视为重叠。
SELECT id, lead(timestampstart) OVER (ORDER BY timestampstart) -
           timestampend AS timetonext
FROM routes;