Redshift - 窗口函数 - 获取每行前一小时的统计信息

Posted

技术标签:

【中文标题】Redshift - 窗口函数 - 获取每行前一小时的统计信息【英文标题】:Redshift - window function - Get stats over previous hour for each row 【发布时间】:2020-01-14 16:06:41 【问题描述】:

我正在尝试根据产品订单为 Redshift 编写查询。 该表包含 store_id、order_number、order_datetime、products_ordered、order_time 等列。我正在尝试编写的查询将从该表中进行选择,并且对于每一行,它将包含一些基于该商店前一小时订单的统计信息。

目前我可以这样做:

SELECT store_id, order_number, order_datetime, products_ordered, order_time,
       (SELECT COUNT(*) FROM mtable WHERE store_id=o.store_id AND order_time BETWEEN (o.order_time - interval '1 hour') AND o.order_time) as prev_num_orders,
       (SELECT AVG(products_ordered) FROM mtable WHERE store_id=o.store_id AND order_time BETWEEN (o.order_time - interval '1 hour') AND o.order_time) as prev_avg_orders
FROM mtable o;

这方面的表现很糟糕。主要原因之一可能是我必须两次查看前几个小时的订单才能获得两个不同的统计数据。有没有办法优化这个?我认为应该有一个窗口功能,但我不确定。

【问题讨论】:

样本数据和期望的结果真的很有帮助。 【参考方案1】:

我想不出这种情况下的有效窗口范围,因为值范围只是公因数。 由于 Redshift 非常擅长处理大型数据集,我建议采用以下解决方案:

SELECT store_id, 
       order_number, 
       order_datetime, 
       products_ordered, 
       order_time, 
       COUNT(prev_orders.store_id) prev_num_orders,
       AVG(prev_orders.products_ordered)  prev_avg_orders
FROM mtable o
left join mtable prev_orders on prev_orders.store_id=o.store_id 
                            AND prev_orders.order_time BETWEEN (o.order_time - interval '1 hour') AND o.order_time 
--and o.order_number != prev_orders.order_number
group by store_id, 
       order_number, 
       order_datetime, 
       products_ordered, 
       order_time;

请注意,prev_num_orders 和 prev_avg_orders 列统计信息也将包括当前订单。从 SQL 语句中取消注释订单号比较行的统计信息消除当前订单。

【讨论】:

【参考方案2】:

我没有测试性能的数据,但是当我在 Redshift 上遇到类似问题时,我就是这样做的:

    with cte as
    (
    SELECT store_id, order_number, order_datetime, products_ordered, order_time,
    LAG (products_ordered,1) OVER (PARTITION BY store_id ORDER BY order_time) AS prev_products_ordered
    from mtable
    )
    select store_id, order_number, order_datetime, products_ordered, order_time,
    count(*) as prev_num_orders, avg(prev_products_ordered) as prev_avg_orders 
from cte
    group by store_id, order_number, order_datetime, products_ordered, order_time

【讨论】:

以上是关于Redshift - 窗口函数 - 获取每行前一小时的统计信息的主要内容,如果未能解决你的问题,请参考以下文章

Redshift Postgres 窗口函数 - rank()

如何在 Redshift SQL 中使用窗口函数

在 Amazon Redshift 中使用窗口函数时需要 GROUP BY 聚合

SQL窗口函数计数前10查询postgresql redshift

表本身的完全外连接并运行一些窗口函数

使用 Spark 流式传输的 Redshift