PostgreSQL window 函数:带条件的分区
PostgreSQL window function: partition with condition
我正在尝试使用以下字段创建查询:
- 数据 - 日期序列
- user_id - 用户 ID
- is_paid - 用户本月支付了吗
- number_of_not_paid - 自上次付款以来的月数,如果付款是在本月,则0
select
date,
user_id,
is_paid,
(case when is_paid
then 0
else sum(case when is_paid then 0 else 1 end) over (partition by user_id order by date)
end)
from data
我得到的结果是:
date
user_id
is_paid
num
2020-01-01
1
true
0
2020-02-01
1
false
1
2020-03-01
1
false
2
2020-04-01
1
true
0
2020-05-01
1
false
3
2020-06-01
1
true
0
我想得到的结果是:
date
user_id
is_paid
num
2020-01-01
1
true
0
2020-02-01
1
false
1
2020-03-01
1
false
2
2020-04-01
1
true
0
2020-05-01
1
false
1
2020-06-01
1
true
0
如何修复我的查询以获得正确的结果?
您想在每次用户付款时重置拖欠计时器,因此每次用户付款时首先标记(boolean
可以转换为 int
以求和):
with runs as (
select date, user_id, is_paid,
sum(is_paid::int) over (partition by user_id
order by date) as run_number
from my_table
)
标记这些运行后,您可以对 (user_id, run_number)
window:
中前面的 false
值求和
select date, user_id, is_paid,
sum((not is_paid)::int) over (partition by user_id, run_number
order by date) as num
from runs;
date | user_id | is_paid | num
:--------- | ------: | :------ | --:
2020-01-01 | 1 | t | 0
2020-02-01 | 1 | f | 1
2020-03-01 | 1 | f | 2
2020-04-01 | 1 | t | 0
2020-05-01 | 1 | f | 1
2020-06-01 | 1 | t | 0
db<>fiddle here
我正在尝试使用以下字段创建查询:
- 数据 - 日期序列
- user_id - 用户 ID
- is_paid - 用户本月支付了吗
- number_of_not_paid - 自上次付款以来的月数,如果付款是在本月,则0
select
date,
user_id,
is_paid,
(case when is_paid
then 0
else sum(case when is_paid then 0 else 1 end) over (partition by user_id order by date)
end)
from data
我得到的结果是:
date | user_id | is_paid | num |
---|---|---|---|
2020-01-01 | 1 | true | 0 |
2020-02-01 | 1 | false | 1 |
2020-03-01 | 1 | false | 2 |
2020-04-01 | 1 | true | 0 |
2020-05-01 | 1 | false | 3 |
2020-06-01 | 1 | true | 0 |
我想得到的结果是:
date | user_id | is_paid | num |
---|---|---|---|
2020-01-01 | 1 | true | 0 |
2020-02-01 | 1 | false | 1 |
2020-03-01 | 1 | false | 2 |
2020-04-01 | 1 | true | 0 |
2020-05-01 | 1 | false | 1 |
2020-06-01 | 1 | true | 0 |
如何修复我的查询以获得正确的结果?
您想在每次用户付款时重置拖欠计时器,因此每次用户付款时首先标记(boolean
可以转换为 int
以求和):
with runs as (
select date, user_id, is_paid,
sum(is_paid::int) over (partition by user_id
order by date) as run_number
from my_table
)
标记这些运行后,您可以对 (user_id, run_number)
window:
false
值求和
select date, user_id, is_paid,
sum((not is_paid)::int) over (partition by user_id, run_number
order by date) as num
from runs;
date | user_id | is_paid | num
:--------- | ------: | :------ | --:
2020-01-01 | 1 | t | 0
2020-02-01 | 1 | f | 1
2020-03-01 | 1 | f | 2
2020-04-01 | 1 | t | 0
2020-05-01 | 1 | f | 1
2020-06-01 | 1 | t | 0
db<>fiddle here