Postgres:日期时间间隔的统计函数

时间:2016-10-11 16:14:51

标签: sql postgresql

我需要对间隔进行一些统计分析,即表格中两个日期时间字段之间的差异。

根据汇总功能文档here。总计 MAXMINAVG等的函数,即一般聚合函数接受日期时间和间隔字段的参数。

但是,对于更高级的统计函数,例如stddev_popvar_popvar_samstd_samp,支持的输入似乎只是数字或类似的。虽然文档表明这两种函数之间没有区别

  

...(这些是分开的,只是为了避免混乱列表   更常用的聚合。)...

有没有简单的方法来计算这些参数?为什么不支持间隔类型作为参数?这些类型的统计聚合函数是单位不变的吗?

P.S。我不确定我是否可以提取时代并使用它,因为某些值可能是负面的。

1 个答案:

答案 0 :(得分:2)

正如我在评论中所说,要手动计算出样本标准差,在某些时候,您将间隔乘以一个间隔。 PostgreSQL不支持。

要解决该问题,请将间隔缩短为小时或分钟或秒(或其他)。事实证明这比手动计算要简单得多,这表明为什么PostgreSQL不支持开箱即用的这种计算。

首先,来自PostgreSQL general mailing list

的函数
CREATE OR REPLACE FUNCTION interval_to_seconds(interval)
RETURNS double precision AS $$
    SELECT (extract(days from $1) * 86400)
         + (extract(hours from $1) * 3600)
         + (extract(minutes from $1) * 60)
         + extract(seconds from $1);
$$ LANGUAGE SQL;

现在我们可以采用一组简单间隔的标准偏差。

with intervals (i) as (
  values (interval '1 hour'), (interval '2 hour'), (interval '3 hour'), 
         (interval '4 hour'), (interval '5 hour') 
)
, intervals_as_seconds as (
  select interval_to_seconds(i) as seconds
  from intervals
)
select stddev(seconds), stddev(seconds)/60
from intervals_as_seconds
in_sec             in_min
double precision   double precision
--
5692.09978830308   94.8683298050514

您可以随意验证结果。

现在让我们说你想要小时粒度而不是秒。显然,粒度的选择取决于应用程序。您可以定义另一个函数interval_to_hours(interval)。您可以使用非常相似的查询来计算标准差。

with intervals (i) as (
  values (interval '1 hour'), (interval '2 hour'), (interval '3 hour'), 
         (interval '4 hour'), (interval '5 hour') 
)
, intervals_as_hours as (
  select interval_to_hours(i) as hours
  from intervals
)
select stddev(hours) as stddev_in_hrs
from intervals_as_hours
stddev_in_hrs
double precision
--
1.58113883008419

以小时为单位的标准差的值明显不同于以分钟或秒为单位的值。但他们衡量的完全相同。重点在于"对"答案取决于您要使用的粒度(单位),并且有很多选择。 (从几微秒到几个世纪,我想。)

另外,请考虑这个陈述。

select interval_to_hours(interval '45 minutes')
interval_to_hours
double precision
--
0

这是正确的答案吗?你不能说;正确的答案取决于应用程序。我可以想象将45分钟视为1小时的应用程序。我还可以想象,对于一些计算,将45分钟视为1小时的应用程序,以及其他计算需要0小时。

考虑一下这个问题。一个月多少秒?表达式select interval '1' month;有效;秒数取决于该月的天数。

我认为 为什么PostgreSQL不支持开箱即用的这种计算。使用区间参数执行此操作的正确方法与应用程序相关。

稍后。 。

我在其中一个PostgreSQL邮件列表上找到了这个讨论。

No stddev() for interval?