Вот некоторые тестовые данные. Как вы можете видеть, CUMULATIVE_VOLUME для четвертого ряда неверно.
SQL> select product_key
2 , trade_date_time
3 , quantity
4 , cumulative_volume
5 , sum (quantity) over (partition by product_key order by sequence_number) as running_total
6 from market_data_intraday_trades
7 order by sequence_number
8 /
PROD TRADE_DAT QUANTITY CUMULATIVE_VOLUME RUNNING_TOTAL
---- --------- ---------- ----------------- -------------
ORCL 23-JUN-10 100 100 100
ORCL 23-JUN-10 50 150 150
ORCL 25-JUN-10 100 250 250
ORCL 26-JUN-10 100 250 350
ORCL 26-JUN-10 50 400 400
ORCL 27-JUN-10 75 475 475
6 rows selected.
SQL>
Самым простым решением является обновление всех строк с вычисленным промежуточным итогом:
SQL> update market_data_intraday_trades m
2 set m.cumulative_volume =
3 ( select inq.running_total
4 from (
5 select sum (quantity) over (partition by product_key
6 order by sequence_number) as running_total
7 , cumulative_volume
8 , rowid as row_id
9 from market_data_intraday_trades
10 ) inq
11 where m.rowid = inq.row_id
12 )
13 /
6 rows updated.
SQL> select product_key
2 , trade_date_time
3 , quantity
4 , cumulative_volume
5 , sum (quantity) over (partition by product_key
6 order by sequence_number) as running_total
7 , rowid as row_id
8 from market_data_intraday_trades
9 order by sequence_number
10 /
PROD TRADE_DAT QUANTITY CUMULATIVE_VOLUME RUNNING_TOTAL
---- --------- ---------- ----------------- -------------
ORCL 23-JUN-10 100 100 100
ORCL 23-JUN-10 50 150 150
ORCL 25-JUN-10 100 250 250
ORCL 26-JUN-10 100 350 350
ORCL 26-JUN-10 50 400 400
ORCL 27-JUN-10 75 475 475
6 rows selected.
SQL>
Однако, если у вас много данных, и вы действительно не хотите, чтобы все эти ненужные обновления, используйте тот же запрос снова, чтобы ограничить попадания:
SQL> update market_data_intraday_trades m
2 set m.cumulative_volume =
3 ( select inq.running_total
4 from (
5 select sum (quantity) over (partition by product_key
6 order by sequence_number) as running_total
7 , cumulative_volume
8 , rowid as row_id
9 from market_data_intraday_trades
10 ) inq
11 where m.rowid = inq.row_id
12 )
13 where m.rowid in
14 ( select inq.row_id
15 from (
16 select sum (quantity) over (partition by product_key
17 order by sequence_number) as running_total
18 , cumulative_volume
19 , rowid as row_id
20 from market_data_intraday_trades
21 ) inq
22 where m.cumulative_volume != running_total
23 )
24
SQL> /
1 row updated.
SQL> select product_key
2 , trade_date_time
3 , quantity
4 , cumulative_volume
5 , sum (quantity) over (partition by product_key
6 order by sequence_number) as running_total
7 from market_data_intraday_trades
8 order by sequence_number
9 /
PROD TRADE_DAT QUANTITY CUMULATIVE_VOLUME RUNNING_TOTAL
---- --------- ---------- ----------------- -------------
ORCL 23-JUN-10 100 100 100
ORCL 23-JUN-10 50 150 150
ORCL 25-JUN-10 100 250 250
ORCL 26-JUN-10 100 350 350
ORCL 26-JUN-10 50 400 400
ORCL 27-JUN-10 75 475 475
6 rows selected.
SQL>
Я попробовал предложение Николаса использовать MERGE. Если вы используете 10 г или выше, то это будет работать. Вам нужна последняя версия Oracle, потому что 9i не поддерживает MERGE с ОБНОВЛЕНИЕМ, но без ВСТАВКИ (а 8i вообще не поддерживает MERGE).
SQL> merge into market_data_intraday_trades m
2 using ( select running_total
3 , row_id
4 from
5 ( select sum (quantity) over (partition by product_key
6 order by sequence_number) as running_total
7 , cumulative_volume
8 , rowid as row_id
9 from market_data_intraday_trades
10 )
11 where cumulative_volume != running_total
12 ) inq
13 on ( m.rowid = inq.row_id )
14 when matched then
15 update set m.cumulative_volume = inq.running_total
16 /
1 row merged.
SQL>
Это решение аккуратнее, чем другое решение.