简体   繁体   中英

How to get count based on column value that reset it in sql query

I want to get the count of column value but with conditional based on other column value. ex: Below the data where first column is identity, second column statusId , third column repeat custId, fourth column status.

id          statusId         CustId      status  

1           1           100         E  
2           1           100         E  
3           1           100         E  
4           2           100         S  
5           1           100         E  
6           1           100         E  
7           2           100         S  
8           1           200         E  
9           1           200         E  
10          2           200         S  
11          2           200         S  
12          1           200         E  
13          2           200         S  

I have used Row_Number() function but it didn't help to achieve it.

select case when Status = 'S' then 0
    when Status = 'E' then sum(case when Status = 'E' then 1 else 0 end) over (order by Id asc) end  as cnt
from cust

Expected Result: I want the result in below format using select query (not any loop).

CusId   ExpectedCount  
100     2              -- there are two rows with status E before last S
200     1              -- There is one row with status E before last S 

To achieve above result, i am counting row that having status E and reset it back to 0 for status S and final count of status E should be returned prior last status S.

Actual result: I am getting count of Status value 'E' and count is not getting reset, its continue to count. Ex.

custId Id Status ExpectedCount
100    1  E      1
100    2  E      2
100    3  E      3
100    4  S      0
100    5  E      4
100    6  E      5
100    7  E      6

THIS ANSWERS THE ORIGINAL VERSION OF THE QUESTION.

You can use a cumulative sum to define the groups and then use row_number() :

select custid, id, status,
       (case when status = 'S' then 0
             else row_number() over (partition by custid, grp, status order by id)
        end) as expectedcount
from (select t.*,
             sum(case when status = 'S' then 1 else 0 end) over (partition by custid order by id) as grp
      from t
     ) t;

Here is a db<>fiddle.

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