#sql #postgresql #sum #aggregate-functions #date-arithmetic
#sql #postgresql #сумма #агрегатные функции #дата-арифметика
Вопрос:
Я пытаюсь СУММИРОВАТЬ два значения, которые вычисляются с использованием функции AGE в PostgreSQL. ВОЗРАСТ должен быть рассчитан как МАКСИМАЛЬНОЕ и МИНИМАЛЬНОЕ значения, связанные с различными (сеансовыми) значениями из этого столбца (значения сеанса различны). Функция AGE должна извлекать минуты из столбца (date_time), а затем также часы из (date_time) и умножать это значение на 60, а затем суммировать эти значения вместе для общего количества минут для сеанса.
Я смог успешно сделать это с
SELECT
session, organization, username,
((date_part('hour',age(MAX(date_time), Min(date_time)))*60) date_part('minute',age(MAX(date_time),
Min(date_time)))) AS Duration
FROM
analysis.user_activity
enter code here
Однако теперь я пытаюсь упорядочить ПО СУММЕ числа, которое возвращает эта функция, на основе СУММЫ продолжительности по ГРУППЕ (организации), просто выполняя заказы ORDER BY (Duration) по наибольшему единичному значению, вычисленному выше, а не всю агрегацию по группе. Вот тут-то и начинаются проблемы. Сначала я попробовал следующим образом:
SELECT
SUM(
(date_part('hour',age(MAX(date_time), Min(date_time)))*60),
date_part('minute',age(MAX(date_time), Min(date_time)))) as SumofDuration
FROM
analysis.user_activity
и я получаю эту ошибку: ОШИБКА: функция sum (двойная точность, двойная точность) не существует Подсказка: ни одна функция не соответствует заданному имени и типам аргументов. Возможно, вам потребуется добавить явные приведения типов. Позиция: 137. Я также получал ошибки о том, что вы не можете вложить агрегатные функции, и поэтому я разделил свой ВЫБОР на несколько шагов, и теперь у меня есть следующее.
SELECT
session, organization, username,
SUM((SELECT date_part('hour',age(MAX(date_time), Min(date_time)))::integer*60
FROM analysis.user_activity)
,
(SELECT date_part('minute',age(MAX(date_time), Min(date_time)))::integer
FROM analysis.user_activity))
ИЗ
analysis.user_activity
Однако это также выдает ошибку ОШИБКА: функция sum(integer, integer) не существует Подсказка: ни одна функция не соответствует заданному имени и типам аргументов. Возможно, вам потребуется добавить явные приведения типов. Позиция: 169. Я также пробовал это с типом numeric. Согласно документации https://www.postgresql.org/docs/8.2/functions-aggregate.html , это ДОЛЖНО быть в состоянии СУММИРОВАТЬ любой из трех типов данных, которые выдает моя функция. Так что же не так?
Заранее спасибо.
Ответ №1:
Я думаю, вы слишком усложняете ситуацию. Если я правильно понимаю, вы можете просто сделать:
select session, organization, username,
extract(epoch from max(date_time) - min(date_time)) / 60 duration_minutes
from analysis.user_activity
group by session, organization, username
Обоснование: max(date_time) - min(date_time)
дает вам интервал; вы можете использовать extract
with epoch
, чтобы преобразовать его в количество секунд, затем разделить результат на 60
, чтобы преобразовать его в минуты.
Обратите внимание, что я также исправил запрос агрегации, в котором отсутствовало group by
предложение. Если вы хотите суммировать продолжительность всех сеансов, добавьте еще один уровень агрегирования:
select sum(duration_seconds) / 60 total_duration_minutes
from (
select extract(epoch from max(date_time) - min(date_time)) duration_seconds
from analysis.user_activity
group by session, organization, username
) t
Комментарии:
1. большое вам спасибо за быстрый ответ. Я новичок в PostgreSQL, и его необычная операция, связанная со временем и датой, заставляет меня вращать колеса. Ваше решение отлично сработало, еще раз спасибо.