运行 余额减少时如何删除和结转前一个月?
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;
相关:
- Counting null values between dates
- Form groups of consecutive rows with same value
- Select longest continuous sequence
我有以下数据:
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;
相关:
- Counting null values between dates
- Form groups of consecutive rows with same value
- Select longest continuous sequence