sql - Redshift SQL Rolling SUM OVER last 3 ids by timestamp(每个 id 有多行)
问题描述
所以我在redshift SQL中有一个名为orders的表,类似于
时间戳 | 客户ID | order_id | 类别 | 牌 | 数量 |
---|---|---|---|---|---|
2020-09-02 09:53:59.000000 | 约翰 | 4213 | 计算机 | 苹果 | 4 |
2020-09-02 09:53:59.000000 | 约翰 | 4213 | 移动的 | 苹果 | 2 |
2020-09-02 09:53:59.000000 | 约翰 | 4213 | 计算机 | 生命值 | 3 |
2020-10-24 00:15:38.000000 | 约翰 | 8321 | 计算机 | 生命值 | 4 |
2020-10-24 00:15:38.000000 | 约翰 | 8312 | 移动的 | 苹果 | 3 |
2021-05-04 02:27:18.000000 | 约翰 | 3214 | 移动的 | 苹果 | 3 |
2021-05-04 02:27:18.000000 | 约翰 | 3124 | 计算机 | 苹果 | 5 |
请注意,order_id 没有特定的基于时间的序列,并且 customer_id 实际上是唯一 ID 而不是名称
我想做的是类似于这样的窗口函数会做什么:
SELECT timestamp,
customer_id,
order_id,
category,
brand
SUM(quantity)
OVER(PARTITION BY customer_id ORDER BY timestamp ASC ROWS 3 PRECEDING) as rolling_sum
FROM order
但是,我不想对当前和前两行进行运行 SUM,而是对当前 id 和前 2 个 order_ids 进行求和,并对每个即将到来的 order_id 执行此操作,因此不仅仅是最后 3 个或前 3 个订单,而是每个订单的最后 3 个订单作为 customer_id 可能有 100 个订单等。
基本上得到这个输出
时间戳 | 顾客姓名 | order_id | 类别 | 牌 | 数量 | 滚动总和 |
---|---|---|---|---|---|---|
2020-09-02 09:53:59.000000 | 约翰 | 4213 | 计算机 | 苹果 | 4 | 4 |
2020-09-02 09:53:59.000000 | 约翰 | 4213 | 移动的 | 苹果 | 2 | 2 |
2020-09-02 09:53:59.000000 | 约翰 | 4213 | 计算机 | 生命值 | 3 | 3 |
2020-10-24 00:15:38.000000 | 约翰 | 8321 | 计算机 | 苹果 | 0 | 4 |
2020-10-24 00:15:38.000000 | 约翰 | 8321 | 计算机 | 生命值 | 4 | 7 |
2020-10-24 00:15:38.000000 | 约翰 | 8312 | 移动的 | 苹果 | 3 | 5 |
2021-05-04 02:27:18.000000 | 约翰 | 3124 | 移动的 | 苹果 | 3 | 8 |
2021-05-04 02:27:18.000000 | 约翰 | 3124 | 计算机 | 苹果 | 5 | 9 |
2021-05-04 02:27:18.000000 | 约翰 | 3124 | 计算机 | 生命值 | 0 | 7 |
据我了解,这对于常规窗口函数是不可能的,并且需要 JOINS 和公用表表达式之间的组合,所以如果您能够看到任何类型的解决方案,我会很高兴听到您的想法。
解决方案
我建议总结和使用窗口函数:
select orderid, customerid, timestamp, sum(quantity) as quantity,
sum(sum(quantity)) over (partition by customerid order by timestamp rows between 3 preceding and current row) as running_quantity_4
from orders
group by orderid, customerid, timestamp;
然后join
回到你的桌子:
select o.*, oct.running_quantity_4
from orders o join
(select orderid, customerid, timestamp, sum(quantity) as quantity,
sum(sum(quantity)) over (partition by customerid order by timestamp rows between 3 preceding and current row) as running_quantity_4
from orders
group by orderid, customerid, timestamp
) oct
on oct.orderid = o.orderid;
推荐阅读
- javascript - 按关键字数组过滤列表并按最佳匹配排序
- c++ - 如何将 OpenCV Mat 设置为 Tensorflow Lite 输入和输出?
- javascript - 在 Cypress 命令中处理多个 Promise
- javascript - 无法读取 null 的属性“clientHeight” - 工作 JSfiddle 教程在其他任何地方都不起作用?
- azure - 如何在 azure devops 模板任务中参数化 azureSubscription
- python - 如何复制子列表中的公共元素?
- c++ - 这些位运算符在做什么?
- placeholder - 是否可以始终在 react-select 中显示占位符?
- azure-ad-b2c - 从一个 AAD B2C 租户迁移用户到另一个 B2C 租户,包括密码
- vba - VBA将一个子的范围传递给另一个子