簡體   English   中英

SQL Window Function 滑動時間 Z05B8C74CBD96FBF2DE4C1A352702FFF4

[英]SQL Window Function over sliding time window

我有以下數據:

            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

該數據描述了object在一個國家/地區單月(2022年7月)的日常使用情況,並非所有object每天都在使用。 我有興趣找到的一件事是該月的每月最大值的總和:

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

我嘗試使用這樣的 window function 無濟於事:

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

有沒有辦法可以在 SQL 中達到預期的結果?

提前致謝。

編輯:對於它的價值,我問了同樣的問題,但在 Pandas 上,我收到了答案; 也許它有助於弄清楚如何在 SQL 中做到這一點。

我們可以將SUM()用作 window function,並按年和月進行分區。

SELECT record_date, country, objectid,
       SUM(objectuse) OVER (PARTITION BY TO_CHAR(record_date, 'YYYY-MM'), country
                            ORDER BY record_date
                            ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS sum
FROM mytable
ORDER BY record_date;
WITH month_max AS (
    SELECT country, objectid,
        MAX(objectuse) over (PARTITION BY objectid ORDER BY record_date) AS maxuse
    FROM mytable
)
SELECT
    country,
    SUM(maxuse)
FROM month_max
GROUP BY country;

這確實假設每個日期每個 object 一行。

最終起作用的可能不是解決此問題的最有效方法。 我基本上從每月的每一天到月初創建了向后看的塊。 在這些桶中的每一個中,我得到了該桶中每個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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM