Postgresql - 24-часовое скользящее окно - PullRequest
0 голосов
/ 23 февраля 2019

В настоящее время я использую Metabase, чтобы собрать живую информационную панель некоторых внутренних показателей компании, и одна из вещей, которые я пытаюсь сделать запрос, - это 24-часовое скользящее окно для транзакций в нашем мобильном приложении.В метабазе есть полезный инструмент визуализации под названием «Умный номер», который позволяет сравнивать изменения значений за определенный период времени. Вот так.

У меня проблемы с написанием запроса, который выводит данные с 24-часовыми интервалами, поэтому я могу сравнить последние 24 часа с 24 часами до этого.Я попытался использовать функцию date_trunc, чтобы разделить транзакции по часам, а затем, возможно, ограничить результаты до последних 24, но он не распечатывает часы, в которых нет транзакций.Я также попытался использовать функцию фильтра, как показано в коде ниже, но данные должны быть транспонированы для работы «умных чисел».У кого-нибудь есть какие-либо предложения относительно того, как мне следует подойти к этой проблеме?

Пример одного из моих подходов:

SELECT 

(DATE_TRUNC('hour', (reservations.created_at::timestamptz)))  as hour,
SUM(reservations.covers) as total_covers  

FROM reservations
JOIN restaurants on restaurants.id = reservations.restaurant_id

WHERE reservations.origin = 'mobile'
and restaurants.relationship_type in ('listing_only', 'difficult', 'ipad')

GROUP BY hour

ORDER BY hour desc

, который выдает что-то вроде этого:

hour                       total_covers
"2019-02-19 15:00:00+00"    4
"2019-02-19 13:00:00+00"    15
"2019-02-19 12:00:00+00"    4
"2019-02-19 11:00:00+00"    4
"2019-02-19 10:00:00+00"    26
"2019-02-19 09:00:00+00"    5
"2019-02-19 08:00:00+00"    8
"2019-02-19 07:00:00+00"    12
"2019-02-19 03:00:00+00"    2

Я хотел бы получить что-то вроде этого:

Time_Interval         Total_Covers
24 Hours                  389
48 Hours                  254
72 hours                  459
96 Hours                  239

Ответы [ 2 ]

0 голосов
/ 23 февраля 2019

Вот пример использования сгенерированной серии для from, а затем соединение слева данных, которые вы хотите считать.Идея состоит в том, что вы хотите, чтобы каждый час появлялся в результате, и каждый фрагмент данных считался, но это необязательно.

Примечание. Я только что проверил скомпилированный запрос;У меня нет фиктивной схемы под рукой, чтобы проверить это.

SELECT 
hours.x as hour,
coalesce(SUM(reservations.covers), 0) as total_covers
FROM (
    select * from generate_series(date_trunc('hour', (now() - INTERVAL '24 hours')), now(), '1 hour')
) hours(x)
LEFT JOIN reservations on hours.x = (DATE_TRUNC('hour', (reservations.created_at::timestamptz)))
LEFT JOIN restaurants on restaurants.id = reservations.restaurant_id
WHERE reservations.origin = 'mobile'
and restaurants.relationship_type in ('listing_only', 'difficult', 'ipad')
GROUP BY hours.x
ORDER BY hours.x desc
0 голосов
/ 23 февраля 2019

В этом запросе для группировки результатов используется функция date.

SELECT 
  DATE(reservations.created_at) AS day,
  SUM(reservations.covers) AS total_covers
FROM reservations
WHERE 
  reservations.origin = 'mobile' AND 
  restaurants.relationship_type IN ('listing_only', 'difficult', 'ipad')
GROUP BY day
ORDER BY day DESC

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

SELECT
  CEIL(EXTRACT(EPOCH FROM NOW() - reservations.created_at) / 86400) as days_ago
  SUM(reservations.covers) as total_covers,
FROM reservations
WHERE 
  reservations.origin = 'mobile' AND 
  restaurants.relationship_type IN ('listing_only', 'difficult', 'ipad')
GROUP BY days_ago
ORDER BY days_ago;

Смотрите это в действии на rextester .

...