在一个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
想知道如果我需要通过一个函数来解压阵列?
许多可能的方法之一: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你可以直接用它来获得你所需要的 - 如果你希望为)
可能是吸引还是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
条款。