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

Posted

技术标签:

【中文标题】获取停止(第 x 行)和开始(第 x+1 行)之间的时间间隔【英文标题】:Get time interval between stop (row x) and start (row x+1) 【发布时间】:2016-04-16 23:05:05 【问题描述】:

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

CREATE TABLE routes(
    ID serial PRIMARY KEY,
    TIMESTAMPSTART timestamp default NULL,
    TIMESTAMPEND timestamp default NULL
);

现在我不想计算开始和停止之间的间隔,而是停止和下一次开始之间的间隔。所以我想要第 x 行的TIMESTAMPSTOP 和第 x+1 行的TIMESTAMPSTART 之间的间隔。顺便说一句,ID 不是按时间顺序排列的!

【问题讨论】:

如果没有“下一个”行会发生什么?如果有重复值怎么办?除了时间戳之外还按ID 排序? 【参考方案1】:

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

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

SQLFiddle

这个解决方案比Erwin's solution快一个数量级:http://www.sqlfiddle.com/#!15/551e2/4

【讨论】:

是的,如果有一个exclusion constraint,这个查询将是等效的,并且更简单、更快。一个极端情况的区别:我的查询假设timestampstart > r.timestampend,而这也允许相等:timestampstart >= r.timestampend。范围类型(​​或 SQL OVERLAPS 运算符)默认将上限视为独占,下一个间隔可以以与上一个结束相同的时间戳开始,并且不被视为重叠。【参考方案2】:

不能只使用简单的window function lead() or lag(),因为您想要两个不同列之间的间隔。

可以使用添加谓词的各种连接变体。有一个索引 timestampstart LATERAL join 和 LIMIT 1 可能是最快的。

假设timestampstartUNIQUE,否则你需要定义如何打破关系。 UNIQUE 约束还可以提供性能所需的索引:

How does PostgreSQL enforce the UNIQUE constraint / what type of index does it use?

SELECT r.*, r1.timestampstart - r.timestampend AS interval_til_start_of_next_row
FROM   routes r
LEFT   JOIN LATERAL (
   SELECT timestampstart
   FROM   routes
   WHERE  timestampstart > r.timestampend
   ORDER  BY timestampstart  -- or BY timestampstart, id - to break ties if not unique
   LIMIT  1
   ) r1 ON true;

【讨论】:

以上是关于获取停止(第 x 行)和开始(第 x+1 行)之间的时间间隔的主要内容,如果未能解决你的问题,请参考以下文章

查询根据时间减去时间来选择行

用Python编写,print("X"),列出1个三角形,第1行1个X居中,第2行2个X居中,第3行5个X居中,列出10行来。

n个元素排成若干行,每行m个,怎么判断第x个元素在哪一行

区间内x的出现个数(主席树)

如果 nick 在文本文件第 x 行

matlab求矩阵的特征值和特征向量