数组中时间戳之间的平均间隔

Posted

技术标签:

【中文标题】数组中时间戳之间的平均间隔【英文标题】:Average interval between timestamps in an array 【发布时间】:2019-02-03 16:31:49 【问题描述】:

在 PostgreSQL 9.x 数据库中,我有一列是时间戳类型的数组。每个数组都有 1..n 个时间戳。

我正在尝试提取每个数组中所有元素之间的平均间隔。

我了解在源表上使用窗口函数可能是解决此问题的理想方法,但在这种情况下,我试图将其作为对数组的操作来执行。

我查看了其他几个问题,这些问题试图计算另一列等的移动平均值或平均值(时间戳列表的中位日期)。

对于示例,我正在寻找一个包含 3 个元素的数组的平均间隔,如下所示:

'"2012-10-09 17:04:05.710887"
 ,"2013-10-18 22:30:08.973749"
 ,"2014-10-22 22:18:18.885973"'::timestamp[]

应该是:

-368d

想知道是否需要通过函数解包数组?

【问题讨论】:

"PostgreSQL 9.x":考虑Postgres versioning。 【参考方案1】:

多种可能中的一种:横向子查询中的unnest、join、avg:

SELECT *
FROM   tbl t
LEFT   JOIN LATERAL (
   SELECT avg(a2.ts - a1.ts) AS avg_intv
   FROM   unnest(t.arr) WITH ORDINALITY a1(ts, ord)
   JOIN   unnest(t.arr) WITH ORDINALITY a2(ts, ord) ON (a2.ord = a1.ord + 1)
   ) avg ON true;

db小提琴here

子查询中的[INNER] JOIN 准确生成与间隔 元素相关的组合集。

我得到371 days 14:37:06.587543,而不是'-368d',顺便说一句。

相关,有更多解释:

PostgreSQL unnest() with element number

您也可以只取消嵌套一次并使用window functions lead() or lag(),但您试图避免使用窗口函数。在任何情况下,您都需要确保元素的原始顺序...

(没有array function 可以直接用来获得所需的东西 - 以防万一。)

CTE 的替代方案

可能只对 unnest 有一次吸引力(即使在避免窗口函数的情况下):

SELECT *
FROM   tbl t
LEFT   JOIN LATERAL (
   WITH   a AS (SELECT * FROM unnest(t.arr) WITH ORDINALITY a1(ts, ord))
   SELECT avg(a2.ts - a1.ts) AS avg_intv
   FROM   a a1
   JOIN   a a2 ON (a2.ord = a1.ord +1)
   ) avg ON true;

但我预计增加的 CTE 开销将超过取消嵌套的两倍。主要只是在子查询中演示 WITH 子句。

【讨论】:

哇强大的答案!我花了几分钟来解决这个问题。非常感谢。

以上是关于数组中时间戳之间的平均间隔的主要内容,如果未能解决你的问题,请参考以下文章

计算一列中时间戳之间的持续时间

Mysql查询将返回数据库中时间戳之间的空闲槽

如何使用 SQL 显示两个不同区域中时间戳之间的实时差异?

python中时间戳,datetime 和时间字符串之间得转换

hsqldb 中时间戳大小的奇怪行为

Hadoop SQL 中时间戳数据类型的奇怪行为