我有以下数据:

            country  objectid  objectuse
record_date
2022-07-20    chile         0          4
2022-07-01    chile         1          4
2022-07-02    chile         1          4
2022-07-03    chile         1          4
2022-07-04    chile         1          4
...             ...       ...        ...
2022-07-26     peru      3088          4
2022-07-27     peru      3088          4
2022-07-28     peru      3088          4
2022-07-30     peru      3088          4
2022-07-31     peru      3088          4

这些数据描述了一个国家内一个对象在一个月(2022年7月)的日常使用情况,并不是所有的对象都每天都在使用.我感兴趣的一件事是该月每月最大值的总和:

WITH month_max AS (
    SELECT
        country,
        objectid,
        MAX(objectuse) AS maxuse
    FROM mytable
    GROUP BY
        country,
        objectid
)
SELECT
    country,
    SUM(maxuse)
FROM month_max
GROUP BY country;

这导致了以下结果:

country   sum
-------------
chile    1224
peru    17008   

但我真正想要的是得到从月初到每个日期的最大值的滚动总和.这样我得到的东西看起来就像:

            country       sum  
record_date
2022-07-01    chile         1
2022-07-01     peru         1
2022-07-02    chile         2
2022-07-02     peru         3
...             ...       ...
2022-07-31    chile       1224
2022-07-31     peru      17008

我try 使用这样的窗口函数,但没有用:

SELECT
    *,
    SUM(objectuse) OVER (
        PARTITION BY country
        ORDER BY record_date ROWS 30 PRECEDING
    ) as cumesum
FROM mytable
order BY cumesum DESC;

有没有一种方法可以在SQL中达到预期效果?

先谢谢你.

编辑:对于它的价值,我问了same question but on Pandas,我得到了答案;也许它有助于弄清楚如何在SQL中做到这一点.

推荐答案

最终奏效的可能不是解决这个问题的最有效方法.我基本上创建了从每月的每一天到月初的回溯块.在这些存储桶中的每个存储桶中,每个存储桶中的objectid个存储桶中的最大值为objectuse.在取了最大值之后,我将所有的最大值相加,这是一个回溯的时期.我在数据中的每一天都这样做.

下面是执行此操作的查询:

WITH daily_lookback AS (
    SELECT
        A.record_date,
        A.country,
        B.objectid,
        MAX(B.objectuse) AS maxuse
    FROM mytable AS A
    LEFT JOIN mytable AS B
        ON A.record_date >= B.record_date
        AND A.country = B.country
        AND DATE_PART('month', A.record_date) = DATE_PART('month', B.record_date)
        AND DATE_PART('year', A.record_date) = DATE_PART('year', B.record_date)
    GROUP BY
        A.record_date,
        A.country,
        B.objectid
)
SELECT
    record_date,
    country,
    SUM(maxuse) AS usetotal
FROM daily_lookback
GROUP BY 
    record_date,
    country
ORDER BY
    record_date;

这正好给出了我正在寻找的结果:回溯时期objectid个最大值的累积和,如下所示:

            country       sum  
record_date
2022-07-01    chile         1
2022-07-01     peru         1
2022-07-02    chile         2
2022-07-02     peru         3
...             ...       ...
2022-07-31    chile       1224
2022-07-31     peru      17008

Sql相关问答推荐

如何在T—SQL中找到值更改之前的日期?

基于时间的SQL聚合

从列的不同值创建列

如何嵌套两条SQL语句

值对于类型字符来说太长

如何使用不重复的单个顶级字段(列)向json数组 Select 多行

从单个表达式中的分隔字符串中取平均值

提取连续时间戳范围的SQL

将伪数据插入Postgres表

无法访问级联删除导致的触发器中已删除的外键记录

SQL:使用年/月/日分区查询某个时间段的数据

SQL 查找 varchar 类型列及其值中多次出现的子字符串

SQL Server - 复杂场景 - 比较状态并填充值到后续行

在SQL中实现表格数据透视类型报表

使用 GROUP BY 时如何创建其他组?

在 postgresql 中保存带有时间戳的几何类型数据

如何对 SQL 表中的连续时间戳进行分组?

如何在 RavenDB Studio (RQL) 中插入更新文档

PostgreSQL 中的递归树查询

如何刷新在视图之上创建的表