Reputation: 143
I have this sample table:
I need to create a rank column that will order the id's based on is_true=1, meaning that every change in is_true from 0 to 1 will increase the index by 1. Something like the following:
I tried something like:
select id, customer_id, is_true,
rank() over (partition by customer_id order by (case when is_true=1 then id end)) index_rank
from table
but it does not give what I need.
Any help will be much appreciated.
Upvotes: 2
Views: 180
Reputation: 5932
improving upon the query provided by GMB
select x.*
,sum(case when (is_true=1 and lag_val=0) or (lag_val is null) then 1 end) over(partition by customer_id order by id) index_rank
from (select *
,lag(is_true) over(partition by customer_id order by id) lag_val
from dbo.t
)x
OLD Query
select id
,customer_id
,is_true
,dense_rank() over(partition by customer_id order by customer_id,max_grp)
from(
select id
,customer_id
,is_true
,max(is_rank) over(partition by customer_id order by id) max_grp
from (select id,customer_id,is_true
,case when is_true=1 and lag(is_true) over(partition by customer_id order by id)=0
or lag(is_true) over(partition by customer_id order by id) is null then
DENSE_RANK() over(partition by customer_id order by id)
end as is_rank
from dbo.t
)x
)y
Upvotes: 1
Reputation: 222632
You can do a window sum:
select
t.*,
1 + sum(is_true) over(partition by cutsomer_id order by id) index_rank
from mytable t
If you want to allow consecutive 1
s without increasing the rank, then you can use lag()
first:
select
t.*,
1 + sum(case when is_true = 1 and lag_is_true = 0 then 1 else 0 end)
over(partition by cutsomer_id order by id) index_rank
from (
select
t.*,
lag(is_true) over(partition by cutsomer_id order by id) lag_is_true
from mytable t
) t
Upvotes: 3