在阵列时间戳之间平均间隔

问题描述 投票:0回答:1

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

我试图提取每个阵列中的所有元件之间的平均间隔。

我了解使用源表上的窗函数可能是解决这个理想的方式,但在这种情况下,我试图做到这一点作为数组的操作。

我看着那些试图计算另一列等或AVG(时间戳列表中位数为准)的移动平均线其他几个问题。

例如,该平均间隔我正在寻找与这样3个元素的阵列上:

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

将会:

-368d

想知道如果我需要通过一个函数来解压阵列?

sql arrays postgresql average intervals
1个回答
2
投票

许多可能的方法之一:UNNEST,加盟,平均在横向子查询:

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;

分贝<>小提琴here

在子查询中的[INNER] JOIN产生完全相同的集合相关的元素之间的时间间隔的组合。

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

相关的,有更多的解释:

您也可以只UNNEST一次,并使用window functions lead() or lag(),但你是故意避开窗口的功能。你需要确保在任何情况下,元素的原顺序的...

(有没有array function你可以直接用它来获得你所需要的 - 如果你希望为)

Alternative with 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开销成本比unnesting两倍以上。大多只是表明在一个子查询一个WITH条款。

© www.soinside.com 2019 - 2024. All rights reserved.