sql - Update a column sequentially based on condition -
i'm on oracle 11g , stuck on problem.
my table structure below
╔═══════╦══════╦════════╗ ║ tm_id ║ flag ║ countr ║ ╠═══════╬══════╬════════╣ ║ 1 ║ 0 ║ null ║ ║ 2 ║ 0 ║ null ║ ║ 3 ║ 1 ║ null ║ ║ 4 ║ 0 ║ null ║ ╚═══════╩══════╩════════╝
i want update values of column countr sequential value below
╔═══════╦══════╦════════╗ ║ tm_id ║ flag ║ countr ║ ╠═══════╬══════╬════════╣ ║ 1 ║ 0 ║ 1 ║ ║ 2 ║ 0 ║ 2 ║ ║ 3 ║ 1 ║ 2 ║ ║ 4 ║ 0 ║ 3 ║ ╚═══════╩══════╩════════╝
so value countr should increase if flag 0. if 1 shouldn't increase (or should have previous value)
i tried following update statement
update calendar set countr = case when flag = 0 tm_id else countr-1 end
oracle 11g r2 schema setup:
create table test ( tm_id, flag, countr ) select 1,0, cast( null number ) dual union select 2,0, cast( null number ) dual union select 3,1, cast( null number ) dual union select 4,0, cast( null number ) dual / update test t set countr = ( select total ( select tm_id, sum( 1 - flag ) on ( order tm_id rows between unbounded preceding , current row ) total test ) x t.tm_id = x.tm_id ) / query 1:
select * test | tm_id | flag | countr | |-------|------|--------| | 1 | 0 | 1 | | 2 | 0 | 2 | | 3 | 1 | 2 | | 4 | 0 | 3 | edit - explanation
the use of sum here analytic function rather than, typically used, aggregate function.
sum( 1 - flag ) on ( order tm_id rows between unbounded preceding , current row ) from (almost) right left:
order tm_id- order rows ascendingtm_id- then each row:
- consider
rows between unbounded preceding , current row(i.e. rows starting earliesttm_idcurrent row) - for rows find
sum( 1 - flag )(i.e. increment counter when flag 0 , not when one).
- consider
Comments
Post a Comment