运行 余额减少时如何删除和结转前一个月?

How to remove and carry forward month prior when running balance decreases?

我有以下数据:

client_id balance_month balance
100000000 September 1,2021 12:00 AM 00
100000000 August 1,2021 12:00 AM 00
100000000 July 1,2021 12:00 AM 00
100000000 June 1,2021 12:00 AM 00
100000000 May 1,2021 12:00 AM 000
100000000 April 1,2021 12:00 AM 00
100000000 March 1,2021 12:00 AM [=11=]
200000000 September 1,2021 12:00 AM 00
200000000 August 1,2021 12:00 AM 00
200000000 July 1,2021 12:00 AM 00
200000000 June 1,2021 12:00 AM 00
200000000 May 1,2021 12:00 AM 00
200000000 April 1,2021 12:00 AM 00
200000000 March 1,2021 12:00 AM [=11=]

我想用余额未减少的最近一个月覆盖余额减少的任何月份。 (假设余额从 2021 年 3 月开始,但希望自动化的时间更长)

client_id balance_month balance
100000000 September 1,2021 12:00 AM 00
100000000 August 1,2021 12:00 AM 00
100000000 July 1,2021 12:00 AM 00
100000000 June 1,2021 12:00 AM 00
100000000 May 1,2021 12:00 AM 00
100000000 April 1,2021 12:00 AM 00
100000000 March 1,2021 12:00 AM [=12=]
200000000 September 1,2021 12:00 AM 00
200000000 August 1,2021 12:00 AM 00
200000000 July 1,2021 12:00 AM 00
200000000 June 1,2021 12:00 AM 00
200000000 May 1,2021 12:00 AM 00
200000000 April 1,2021 12:00 AM 00
200000000 March 1,2021 12:00 AM [=12=]

假设所有列 NOT NULL,否则您需要做更多。

SELECT client_id, balance_month
     , COALESCE(balance_null, first_value(balance_null) OVER (PARTITION BY client_id, balance_grp ORDER BY balance_month)) AS new_balance
FROM  (
   SELECT *
        , count(balance_null) OVER (PARTITION BY client_id ORDER BY balance_month) AS balance_grp
   FROM  (
      SELECT client_id, balance_month
           , CASE WHEN lead(balance) OVER (PARTITION BY client_id ORDER BY balance_month) < balance THEN NULL ELSE balance END AS balance_null
      FROM   tbl
      ORDER  BY client_id, balance_month
      ) sub1
   ) sub2;

db<>fiddle here

在子查询 sub1 中,如果下一行的 balance 较小(您的替换条件),则将 balance 设置为 NULL。

在子查询 sub2 中,为连续的 NULL 值形成组,包括使用 count(balance_null) 的前导非空值 (balance_grp),因为它从计数中省略了 NULL 值,因此每个NULL 值属于具有最后一个有效(非空)值的组。

在外部 SELECT 中,将 NULL 值替换为每个组中的前导非空值。瞧。

如果可以假设 balance 在所有非违规行中稳定增长(或至少停滞),我们可以使用更简单的查询:

SELECT client_id, balance_month
     , COALESCE(balance_null, max(balance_null) OVER (PARTITION BY client_id ORDER BY balance_month))
FROM  (
   SELECT client_id, balance_month
        , CASE WHEN lead(balance) OVER (PARTITION BY client_id ORDER BY balance_month) < balance THEN NULL ELSE balance END AS balance_null
   FROM   tbl
   ORDER  BY client_id, balance_month
   ) sub1;

相关: