Как я уже сказал в комментарии, чтобы вручную выставить образец стандартного отклонения, в какой-то момент вы умножаете интервал на интервал. 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?
Разница между двумя полями даты и времени поражает меня как числовой. –
Thats, что я также думал, однако разница - это интервал типа даты, и эти функции не принимают интервальные входы, avg делает, хотя это не имеет никакого смысла для меня. – Manquer
@DanBracuk различие между двумя «timestamps» - это 'interval' –