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 

sql fiddle

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 

results:

| 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 ascending tm_id
  • then each row:
    • consider rows between unbounded preceding , current row (i.e. rows starting earliest tm_id current row)
    • for rows find sum( 1 - flag ) (i.e. increment counter when flag 0 , not when one).

Comments

Popular posts from this blog

javascript - Google App Script ContentService downloadAsFile not working -

javascript - Function overwritting -

php - Find a regex to take part of Email -