Postgres - различные агрегации, основанные на значениях столбца - PullRequest
0 голосов
/ 07 ноября 2019

У меня есть таблица, которая позволяет пользователям хранить различные метрики для devices. devices могут быть разных типов (например, IoT) и иметь разные метрики.

например, устройство слежения за парком может иметь speed, distanceTravelled, tripDuration, в то время как сельскохозяйственный датчик может иметь temperature, humidity.

Обратите внимание, что в одном активе необязательно одинаковое количество метрик. например, tripDuration может обновляться только несколько раз в день, тогда как speed может обновляться два раза в минуту.

create table metric_history
(
  device_id     uuid not null,
  timestamp     timestamp,
  metric_name   text,
  value         double precision
);

В настоящее время я работаю в системе, которая позволяет пользователям запускать пользовательские исторические отчеты. на своих устройствах. Эти отчеты представляют собой сводные отчеты.

Например, клиент отслеживания флота может захотеть создать отчет для каждого из своих устройств за текущую неделю:

  • Макс. Скорость: MAX(speed)
  • Средняя скорость: AVG(speed)
  • Количество поездок: COUNT(tripDuration)
  • Средняя длина поездки: AVG(tripDuration)
  • и т. Д.

Как мне поступить так: (надеюсь, несколько эффективно)? Пытаясь придумать способ приблизиться к нему.

Ответы [ 2 ]

2 голосов
/ 07 ноября 2019

Используйте предложение FILTER , например:

select
    device_id,
    max(value) filter (where metric_name = 'speed') as max_speed,
    avg(value) filter (where metric_name = 'speed') as avg_speed,
    count(value) filter (where metric_name = 'tripDuration') as number_of_trips
from metric_history
group by device_id
0 голосов
/ 07 ноября 2019

Если вы хотите получить все значения в одном и том же выборе, вы можете сделать это:

SELECT MAX(CASE WHEN device_id=X THEN value ELSE 0 END) AS speed,
       AVG(CASE WHEN device_id=Y THEN value ELSE null END) AS tripDuration
  FROM metric_history

PS: Когда вы отбрасываете значение в AVG, вам нужно установить значение NULL, чтобы не учитывать элемент в среднем.

...