PostgreSQL-24小时滚动窗口

时间:2019-02-23 19:39:08

标签: postgresql metabase

我目前正在使用Metabase来构建一个实时的仪表板,其中包含一些公司内部指标,而我要查询的一件事是在我们的移动应用程序上进行24小时滚动的交易窗口。 Metabase有一个有用的可视化工具,称为“智能编号”,它使您可以比较定义的时间段内值的变化。 Like this.

我在编写以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 :(得分:1)

此查询使用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;

See it in action on rextester

答案 1 :(得分:0)

这里是一个为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