Presto 中按 id 和按月的累计总和

Art*_*tem 5 sql presto amazon-athena

在 Amazon Athena 中,我有一个如下所示的表:

id   amount date
1    100    2018-04-05
1    50     2018-06-18
2    10     2018-04-23
2    100    2018-04-28
2    50     2018-07-07
2    10     2018-08-08
Run Code Online (Sandbox Code Playgroud)

我想要这样的结果

id   cum_sum date
1    100    2018-04
1    100    2018-05
1    150    2018-06
1    150    2018-07
1    150    2018-08
2    110    2018-04
2    110    2018-05
2    110    2018-06 
2    160    2018-07
2    170    2018-08
Run Code Online (Sandbox Code Playgroud)

所以我想要每个月底(每月最后一天)每个 ID 的累计金额。我知道如何逐月执行此操作,但不知道如何在一次查询中执行此操作。

另一个问题还在于填充空月份(即 ID 1 没有所有月份的条目,因此必须重新使用累积和)。

如果也有 MySQL 的解决方案,我也会很感激。

我希望这是有道理的,并提前致谢。

Tim*_*sen 0

这是 MySQL 8+ 解决方案,但可以轻松适应早期版本或支持 CTE 的其他数据库。它使用日历表来存储id值和日期。生成跨月/id 的金额后,进行累加求和以获得最终结果。

WITH ids AS (
    SELECT 1 AS id FROM dual UNION ALL
    SELECT 2 FROM dual
),
months AS (
    SELECT '2018-04-01' AS month UNION ALL    -- use the first of the month
    SELECT '2018-05-01' UNION ALL             -- to represent a given month
    SELECT '2018-06-01' UNION ALL
    SELECT '2018-07-01' UNION ALL
    SELECT '2018-08-01'
),
cte AS (
    SELECT
        i.id,
        m.month,
        SUM(amount) AS amount
    FROM ids i
    CROSS JOIN months m
    LEFT JOIN yourTable t
        ON t.id = i.id AND
           t.date >= m.month AND t.date < DATE_ADD(m.month, INTERVAL 1 MONTH)
    GROUP BY
        i.id,
        m.month
)

SELECT
    id,
    (SELECT SUM(t2.amount) FROM cte t2
     WHERE t1.id = t2.id AND t2.month <= t1.month) cum_sum,
    DATE_FORMAT(month, '%Y-%m') AS date
FROM cte t1
ORDER BY
    id,
    month;
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

演示

让上述内容在早期版本的 MySQL 或 PrestoDB 上运行的主要挑战取决于是否可能删除 CTE 以及日期函数逻辑。除此之外,查询应该保持不变。