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

标签 sql arrays postgresql average intervals

在 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、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<> fiddle here

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

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

相关,有更多解释:

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

(没有 array function 你可以直接使用来获得你需要的东西 - 如果你希望那样的话。)

CTE 的替代方案

可能仍然只嵌套一次(即使在避免窗口函数的情况下):

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 子句。

关于sql - 数组中时间戳之间的平均间隔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54505036/

相关文章:

postgresql - 将 PouchDB 离线同步到 PostgreSQL

带有单独凭证文件的 Django PostgreSQL 设置?

java - 字段 'user_id' 没有默认值,但设置为 auto_increment

c# - 为什么存储过程输出参数没有被 Entity Framework 的 ExecuteSqlCommand 方法读取?

arrays - 创建间隔内的整数列表

C 插入排序程序因输入较多而失败

postgresql - 有多次通过 : How to select records with no relation OR by some condition in relation?

php - 进行仅显示不包含空值的行的查询

sql - 有关按时间顺序检索数据的数据库设计/SQL 的建议

php - 如何按值过滤多维数组(超过两级)?