Reputation: 3
Here is my input and expected output. I tried using ranks and flags to identify how to reset the rank and can’t seem to get it to work.
Input:
Type Date Rank
PA 1/1/2000 1
ON 1/2/2000 2
Acq 1/4/2000 3
PA 2/1/2000 4
ON 4/2/2000 5
ON 6/3/2000 6
PA 6/11/2000 7
Output:
Type Date Rank
PA 1/1/2000 1
ON 1/2/2000 2
Acq 1/4/2000 3
PA 2/1/2000 1
ON 4/2/2000 2
ON 6/3/2000 3
PA 6/11/2000 1
Basically whenever type equals PA it should reset the count.
Trying to do this is in BigQuery
Upvotes: 0
Views: 435
Reputation: 1269873
You can do this by defining groups using a cumulative count of 'PA'
. I recommend countif()
:
select i.*, row_number() over (partition by grp order by date) as ranking
from (select i.*,
countif(type = 'PA') over (order by date) as grp
from input i
) i;
If you already have rank
as a column, you could also just subtract out the most recent value of 'PA'
. That would be:
select t.*,
(ranking + 1 -
coalesce(max(case when type = 'PA' then ranking end) over (order by ranking), 1)
) as new_ranking
from input
Upvotes: 2
Reputation: 2365
You can create a virtual group using PA. So every time a new PA row comes group index increases by 1. I named that column as reset_group.
Then, I used this column as the partition column and used row_number() to calculate rank within the group.
WITH
data AS
(
SELECT 'PA' as Type, '2000-01-01' as DATE UNION ALL
SELECT 'ON' as Type, '2000-01-02' as DATE UNION ALL
SELECT 'Acq' as Type, '2000-01-04' as DATE UNION ALL
SELECT 'PA' as Type, '2000-02-01' as DATE UNION ALL
SELECT 'ON' as Type, '2000-03-02' as DATE UNION ALL
SELECT 'ON' as Type, '2000-06-03' as DATE UNION ALL
SELECT 'PA' as Type, '2000-06-11' as DATE
),
reset_groups AS
(
select *, SUM(IF(Type = 'PA', 1, 0)) OVER (ORDER BY Date) as reset_group
from data
)
select *, ROW_NUMBER() OVER (PARTITION BY reset_group ORDER BY Date) as rank
from reset_groups
Upvotes: 1