简体   繁体   中英

For each row count how many previous rows fall behind based on the date SQL BigQuery

I have a table in BigQuery with repayment subscription plan which looks like this:

id sub_month_number to_be_paid_date actual_payment_date was_late
156 1 2020-03-01 2020-03-01 no
156 2 2020-04-01 2021-06-02 yes
156 3 2020-05-01 2020-06-07 yes
156 4 2020-06-01 2021-06-07 yes

For each customer id there is subscription month number and the date when we expect them to pay for their subscription. I know which payments came in later than expected, but I'd like to know many previous months were unpaid at the time when the next payment was due.

For example by the time when subscription for month 4 was due (2020-06-01) months 2 and 3 were still unpaid. So I'm trying to calculate something like this num_past_overdue :

id sub_month_number to_be_paid_date actual_payment_date num_past_overdue
156 1 2020-03-01 2020-03-01 -
156 2 2020-04-01 2021-06-02 0
156 3 2020-05-01 2020-06-07 1
156 4 2020-06-01 2021-06-07 2

I tried using LEAD function and CASE WHEN, but it only gives me the information whether the preceding month was paid, not how many previous months were unpaid at the time when the next months is due.

WITH payments as (
SELECT *
,LEAD(to_be_paid_date) OVER (PARTITION BY id ORDER BY id,  to_be_paid_date) AS next_due_date  
FROM table)

SELECT *
, CASE WHEN DATE_DIFF(actual_payment_date, next_due_date, DAY)> 0 THEN True
          ELSE False END AS overdue_when_next_was_due
FROM payments

Try the approach below:

with t1 as (
  select 156 as id, 1 as sub_month_number, date('2020-03-01')   as to_be_paid_date, date('2020-03-01')  as actual_payment_date, 'no' as was_late,
  union all select 156 as id, 2 as sub_month_number, date('2020-04-01') as to_be_paid_date, date('2021-06-02') as actual_payment_date, 'yes' as was_late,
  union all select 156 as id, 3 as sub_month_number, date('2020-05-01') as to_be_paid_date, date('2020-06-07') as actual_payment_date, 'yes' as was_late,
  union all select 156 as id, 4 as sub_month_number, date('2020-06-01') as to_be_paid_date, date('2021-06-07') as actual_payment_date, 'yes' as was_late,
)

select 
  *,
  sum(
    case 
      when was_late='yes' then 1 
      else 0 
    end
    ) over(order by actual_payment_date) as num_past_overdue
from t1

Output: 在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM