3天窗口滚动求和异常:同日期行重复计算及数据缺失
解决3天滚动金额求和中的重复行与数据异常问题
原始交易数据
| 交易ID(transaction_id) | 用户ID(user_id) | 金额(amount) | 交易日期(transaction_date) |
|---|---|---|---|
| 354 | 423 | 240.13 | 01/01/2022 12:00:00 |
| 2425 | 423 | 167.24 | 01/03/2022 12:00:00 |
| 1352 | 423 | 234.14 | 01/03/2022 12:00:00 |
| 2145 | 423 | 123.45 | 01/04/2022 12:00:00 |
| 1544 | 423 | 82.90 | 01/06/2022 12:00:00 |
| 1223 | 525 | 124.20 | 01/01/2022 12:00:00 |
| 1732 | 525 | 324.00 | 01/02/2022 12:00:00 |
| 1413 | 525 | 100.50 | 01/03/2022 12:00:00 |
| 1141 | 525 | 123.00 | 01/03/2022 12:00:00 |
| 1341 | 525 | 198.35 | 01/04/2022 12:00:00 |
| 2362 | 826 | 146.24 | 01/02/2022 12:00:00 |
| 1234 | 826 | 242.00 | 01/04/2022 12:00:00 |
原SQL查询
SELECT user_id, transaction_date, SUM(amount) OVER( PARTITION BY user_id ORDER BY transaction_date RANGE BETWEEN interval '2 days' PRECEDING AND CURRENT ROW ) AS rolling_earnings_3d FROM user_transactions;
错误输出
| user_id | transaction_date | rolling_earnings_3d |
|---|---|---|
| 423 | 01/01/2022 12:00:00 | 240.13 |
| 423 | 01/03/2022 12:00:00 | 641.51 |
| 423 | 01/03/2022 12:00:00 | 641.51 |
| 423 | 01/04/2022 12:00:00 | 524.83 |
| 423 | 01/06/2022 12:00:00 | 206.35 |
| 525 | 01/01/2022 12:00:00 | 124.20 |
| 525 | 01/02/2022 12:00:00 | 448.20 |
| 525 | 01/03/2022 12:00:00 | 671.70 |
| 525 | 01/03/2022 12:00:00 | 671.70 |
| 525 | 01/04/2022 12:00:00 | 745.85 |
| 826 | 01/02/2022 12:00:00 | 146.24 |
期望输出
| user_id | transaction_date | rolling_earnings_3d |
|---|---|---|
| 423 | 01/01/2022 12:00:00 | 240.13 |
| 423 | 01/03/2022 12:00:00 | 641.51 |
| 423 | 01/04/2022 12:00:00 | 524.83 |
| 423 | 01/06/2022 12:00:00 | 206.35 |
| 525 | 01/01/2022 12:00:00 | 124.20 |
| 525 | 01/02/2022 12:00:00 | 448.20 |
| 525 | 01/03/2022 12:00:00 | 671.70 |
| 525 | 01/04/2022 12:00:00 | 745.85 |
| 826 | 01/02/2022 12:00:00 | 146.24 |
| 826 | 01/04/2022 12:00:00 | 530.24 |
| 826 | 01/07/2022 12:00:00 | 100.00 |
问题分析与解决方案
问题原因
- 同日期重复行:原查询直接对单条交易计算滚动和,同一用户同一天的多笔交易都会返回相同的滚动结果,导致输出重复行。
- 用户826数据缺失:原查询未返回用户826的01/04交易行,核心原因是未先聚合每日金额,窗口统计逻辑未覆盖完整数据;另外期望输出中01/07的交易行需确保原始数据包含该记录。
解决步骤
- 聚合每日金额:按
user_id和transaction_date分组,合并同一天的多笔交易为一行,消除重复输出的根源。 - 基于聚合数据计算滚动和:对每日聚合后的数据应用窗口函数,确保每个日期只返回一行结果,同时正确计算前2天到当前日期的金额总和。
修正后的SQL
WITH daily_transactions AS ( SELECT user_id, transaction_date, SUM(amount) AS daily_amount FROM user_transactions GROUP BY user_id, transaction_date ) SELECT user_id, transaction_date, SUM(daily_amount) OVER( PARTITION BY user_id ORDER BY transaction_date RANGE BETWEEN INTERVAL '2 days' PRECEDING AND CURRENT ROW ) AS rolling_earnings_3d FROM daily_transactions ORDER BY user_id, transaction_date;
说明
daily_transactionsCTE先完成每日金额聚合,避免同日期多行重复。- 窗口函数基于聚合后的数据计算,确保每个日期仅返回一个滚动和结果。
- 用户826的01/04交易行,聚合后滚动和会包含01/02的金额,若期望输出为530.24需检查原始数据是否存在其他补充交易;01/07的100.00交易需确保该记录存在于
user_transactions表中。
内容的提问来源于stack exchange,提问作者ELM
相关产品推荐
相关产品推荐

