PostgreSQL window 函数:带条件的分区

PostgreSQL window function: partition with condition

我正在尝试使用以下字段创建查询:

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