数组中时间戳之间的平均间隔
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
子句。
【讨论】:
哇强大的答案!我花了几分钟来解决这个问题。非常感谢。以上是关于数组中时间戳之间的平均间隔的主要内容,如果未能解决你的问题,请参考以下文章