Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 按id和月份的累计金额(以Presto为单位)_Sql_Amazon Athena_Presto - Fatal编程技术网

Sql 按id和月份的累计金额(以Presto为单位)

Sql 按id和月份的累计金额(以Presto为单位),sql,amazon-athena,presto,Sql,Amazon Athena,Presto,在亚马逊雅典娜,我有一张这样的桌子: 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 我想要一个结果,比如 id cum_sum date 1 100 2018-04 1 100 2018-05 1 1

在亚马逊雅典娜,我有一张这样的桌子:

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
我想要一个结果,比如

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
所以我想知道每个月最后一天每个ID在月底的累计金额。我知道如何逐月进行,但不是一次查询

另一个问题是填充空月份,即ID 1没有所有月份的条目,因此必须重新使用累积总和

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


我希望这是有意义的,并提前表示感谢

这里有一个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;

在MySQL的早期版本或PrestoDB上实现上述功能的主要挑战在于是否可能删除CTE,以及日期函数逻辑。除此之外,查询应保持不变。

您可以在PrestoDB中使用窗口函数。您可以生成日期。也很简单,只需列出以下内容:

with months as (
      selecct '2018-04-01' as yyyy_mm union all    -- use the first of the month
      select '2018-05-01' union all
      select '2018-06-01' union all
      select '2018-07-01' union all
      select '2018-08-01'
     )
select i.id, m.yyyy_mm, sum(t.amt) as month_amount,
       sum(sum(t.amt)) over (partition by i.id order by m.yyyy_mm) as cumulative_amt
from (select distinct id from t) i cross join
     months m left join
     t
     on t.id = i.id and
        t.date >= m.yyyy_mm and
        t.date < m.yyyy_mm + interval '1 day'
group by i.id, m.yyyy_mm
order by i.id, m.yyyy_mm;

这在MySQL 8.0中也应该适用。在早期版本中,需要变量或相关子查询。第一个在PrestoDB中不起作用。第二个可能会有更糟糕的性能。

通过重写一点,我成功地获得了我在Presto中想要的结果。我添加了一个更加动态的日期范围,所有ID都是250000,我似乎很快就得到了一个合适的结果。