我需要对间隔进行一些统计分析,即表格中两个日期时间字段之间的差异。
根据汇总功能文档here。总计
MAX
,MIN
,AVG
等的函数,即一般聚合函数接受日期时间和间隔字段的参数。
但是,对于更高级的统计函数,例如stddev_pop
,var_pop
,var_sam
和std_samp
,支持的输入似乎只是数字或类似的。虽然文档表明这两种函数之间没有区别
...(这些是分开的,只是为了避免混乱列表 更常用的聚合。)...
有没有简单的方法来计算这些参数?为什么不支持间隔类型作为参数?这些类型的统计聚合函数是单位不变的吗?
P.S。我不确定我是否可以提取时代并使用它,因为某些值可能是负面的。
答案 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邮件列表上找到了这个讨论。