[英]Update a column sequentially based on condition
我使用的是oracle 11g,因此無法解決這個問題。
我的表結構如下
╔═══════╦══════╦════════╗ ║ tm_id ║ flag ║ countr ║ ╠═══════╬══════╬════════╣ ║ 1 ║ 0 ║ null ║ ║ 2 ║ 0 ║ null ║ ║ 3 ║ 1 ║ null ║ ║ 4 ║ 0 ║ null ║ ╚═══════╩══════╩════════╝
我想使用以下順序值更新列計數器的所有值
╔═══════╦══════╦════════╗ ║ tm_id ║ flag ║ countr ║ ╠═══════╬══════╬════════╣ ║ 1 ║ 0 ║ 1 ║ ║ 2 ║ 0 ║ 2 ║ ║ 3 ║ 1 ║ 2 ║ ║ 4 ║ 0 ║ 3 ║ ╚═══════╩══════╩════════╝
因此,基本上,countr的值僅應在標志為0時增加。如果為1,則不應增加(或應具有先前的值)
我嘗試了以下更新聲明
UPDATE calendar
SET countr = case when flag = 0 then tm_id else countr-1 end
Oracle 11g R2架構設置 :
CREATE TABLE test ( tm_id, flag, countr ) AS
SELECT 1,0, CAST( NULL AS NUMBER ) FROM DUAL
UNION ALL SELECT 2,0, CAST( NULL AS NUMBER ) FROM DUAL
UNION ALL SELECT 3,1, CAST( NULL AS NUMBER ) FROM DUAL
UNION ALL SELECT 4,0, CAST( NULL AS NUMBER ) FROM DUAL
/
UPDATE test t
SET countr = ( SELECT total
FROM (
SELECT tm_id,
SUM( 1 - FLAG ) OVER ( ORDER BY tm_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS total
FROM test
) x
WHERE t.tm_id = x.tm_id
)
/
查詢1 :
SELECT * FROM test
結果 :
| TM_ID | FLAG | COUNTR |
|-------|------|--------|
| 1 | 0 | 1 |
| 2 | 0 | 2 |
| 3 | 1 | 2 |
| 4 | 0 | 3 |
編輯-說明
SUM
在這里用作分析函數,而不是通常使用的聚合函數。
SUM( 1 - FLAG ) OVER ( ORDER BY tm_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW )
從(幾乎)右到左:
ORDER BY tm_id
升序tm_id
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
(從最早的開始,即只有行tm_id
當前行) SUM( 1 - FLAG )
(即,當標志為零時增加計數器,而不是為1時遞增計數器)。 您要在update
使用子查詢:
update calendar t
set countr = (select count(*)
from calendar t2
where t2.tm_id <= t.tm_id and t2.flag = 0
);
如果表很大,您可能會發現merge
效率更高。
您應該使用光標。 從表中獲取所有行。 根據情況,循環更新一行一行。 將計數值存儲在循環的最后一個聲明變量中。 如果flag = 1,則在下一循環中使用此變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.