Reputation: 15
in the below table i'm trying to enter the number of times the same status repeated after another status. if the status remains the same and the event status order is sequential then the count shouldn't increase. if the status change and enters the same status again ,the count should increase
sid status order num_times_status_entered_again Expected result
1 A 1 1 1
1 A 2 2 1
1 B 3 1 1
1 C 4 1 1
1 A 5 3 2
1 B 7 3 2
1 B 8 4 2
1 B 9 5 2
1 C 10 2 2
1 A 11 4 3
1 B 13 7 3
1 B 14 8 3
1 B 15 9 3
1 D 16 1 1
1 E 17 1 1
2 A 1 1 1
2 A 2 2 1
2 B 3 1 1
2 B 4 2 1
2 A 5 3 2
this is the query I'm using
update t
set num_times_status_entered_again = t1.Ncount
from #tableZ t,(select status
count(1) OVER (Partition by status order by status) as Ncount
from #sub_tableZ
where status is not null
group by status, date
) t1 GROUP BY sid
Upvotes: 0
Views: 104
Reputation: 4694
Here's a query which generates the required result, I think:
same_stat
and seq_ord
are derived in the xrows
CTE term using CASE ... END
expressions.
LAG(status) OVER (ORDER BY sid, ord)
provides the status
value in the previous row based on sid, ord
ordering.
LAG(ord ) OVER (ORDER BY sid, ord)
provides the ord
value in the previous row based on sid, ord
ordering, to decide if the last order value
and the current order value
have a gap between them.
For SQL Server:
WITH xrows AS (
SELECT t.*
, CASE WHEN status = LAG(status, 1, 'NA') OVER (ORDER BY sid, ord) THEN 1 ELSE 0 END AS same_stat
, CASE WHEN ord-1 = LAG(ord , 1, ord ) OVER (ORDER BY sid, ord) THEN 1 ELSE 0 END AS seq_ord
FROM test AS t
)
SELECT t.*
, SUM(CASE WHEN same_stat = 1 AND seq_ord = 1 THEN 0 ELSE 1 END) OVER (PARTITION BY sid, status ORDER BY ord) AS xseq
FROM xrows AS t
ORDER BY sid, ord
;
For MySQL:
WITH xrows AS (
SELECT t.*
, status = COALESCE(LAG(status) OVER (ORDER BY sid, ord) , 'NA') AS same_stat
, ord-1 = COALESCE(LAG(ord ) OVER (ORDER BY sid, ord) , ord) AS seq_ord
FROM test AS t
)
SELECT t.*
, SUM(CASE WHEN same_stat AND seq_ord THEN 0 ELSE 1 END) OVER (PARTITION BY sid, status ORDER BY ord) AS xseq
FROM xrows AS t
ORDER BY sid, ord
;
The result:
+------+--------+------+-----------+---------+------+
| sid | status | ord | same_stat | seq_ord | xseq |
+------+--------+------+-----------+---------+------+
| 1 | A | 1 | 0 | 0 | 1 |
| 1 | A | 2 | 1 | 1 | 1 |
| 1 | B | 3 | 0 | 1 | 1 |
| 1 | C | 4 | 0 | 1 | 1 |
| 1 | A | 5 | 0 | 1 | 2 |
| 1 | B | 7 | 0 | 0 | 2 |
| 1 | B | 8 | 1 | 1 | 2 |
| 1 | B | 9 | 1 | 1 | 2 |
| 1 | C | 10 | 0 | 1 | 2 |
| 1 | A | 11 | 0 | 1 | 3 |
| 1 | B | 13 | 0 | 0 | 3 |
| 1 | B | 14 | 1 | 1 | 3 |
| 1 | B | 15 | 1 | 1 | 3 |
| 1 | D | 16 | 0 | 1 | 1 |
| 1 | E | 17 | 0 | 1 | 1 |
| 2 | A | 1 | 0 | 0 | 1 |
| 2 | A | 2 | 1 | 1 | 1 |
| 2 | B | 3 | 0 | 1 | 1 |
| 2 | B | 4 | 1 | 1 | 1 |
| 2 | A | 5 | 0 | 1 | 2 |
+------+--------+------+-----------+---------+------+
The setup:
CREATE TABLE test (
sid int
, status varchar(5)
, ord int
);
INSERT INTO test VALUES
( 1 ,'A' ,1 )
, ( 1 ,'A' ,2 )
, ( 1 ,'B' ,3 )
, ( 1 ,'C' ,4 )
, ( 1 ,'A' ,5 )
, ( 1 ,'B' ,7 )
, ( 1 ,'B' ,8 )
, ( 1 ,'B' ,9 )
, ( 1 ,'C' ,10 )
, ( 1 ,'A' ,11 )
, ( 1 ,'B' ,13 )
, ( 1 ,'B' ,14 )
, ( 1 ,'B' ,15 )
, ( 1 ,'D' ,16 )
, ( 1 ,'E' ,17 )
, ( 2 ,'A' ,1 )
, ( 2 ,'A' ,2 )
, ( 2 ,'B' ,3 )
, ( 2 ,'B' ,4 )
, ( 2 ,'A' ,5 )
;
Upvotes: 1