これにはPL/SQLは必要ありませんが、1つのMERGE文で実行できます。
まず第一に、あなたは後にしている結果を取得する方法を考え出す - そのようにあなたは、「LAST_VALUE()」解析関数を使用してこれを行うことができます。
WITH your_table AS (SELECT 1 id, 'xxx;yyy;zzz;123456;' column1, NULL column2 FROM dual UNION ALL
SELECT 2 id, 'aaa' column1, NULL column2 FROM dual UNION ALL
SELECT 3 id, 'bbb' column1, NULL column2 FROM dual UNION ALL
SELECT 4 id, 'ccc' column1, NULL column2 FROM dual UNION ALL
SELECT 5 id, 'ddd' column1, NULL column2 FROM dual UNION ALL
SELECT 6 id, 'eee' column1, NULL column2 FROM dual UNION ALL
SELECT 7 id, 'xxx;yyy;zzz;789123;' column1, NULL column2 FROM dual UNION ALL
SELECT 8 id, 'aaa' column1, NULL column2 FROM dual)
select id,
column1,
last_value(CASE WHEN substr(column1, -1) = ';' THEN
regexp_substr(column1, ';*([[:digit:]]*)(;$)', 1, 1, NULL, 1)
END IGNORE NULLS) OVER (ORDER BY ID) column2
from your_table;
ID COLUMN1 COLUMN2
---------- ------------------- -------------------
1 xxx;yyy;zzz;123456; 123456
2 aaa 123456
3 bbb 123456
4 ccc 123456
5 ddd 123456
6 eee 123456
7 xxx;yyy;zzz;789123; 789123
8 aaa 789123
そして、あなたがそれを使用することができます以下のようなので、アップデートを行うにはMERGE文:
MERGE INTO your_table tgt
USING (select id,
column1,
CASE WHEN substr(column1, -1) = ';' THEN 'Y' ELSE 'N' END driving_column1,
last_value(CASE WHEN substr(column1, -1) = ';' THEN
regexp_substr(column1, ';*([[:digit:]]*)(;$)', 1, 1, NULL, 1)
END IGNORE NULLS) OVER (ORDER BY ID) column2 -- assuming id drives the correct order to use here
from your_table) src
ON (tgt.id = src.id) -- assuming id is the primary key of your_table
WHEN MATCHED THEN
UPDATE SET tgt.column2 = src.column2;
あなたは値が(私は存在セミコロンがあることを、CSV値を仮定してきたしているCOLUMN1行の列2を更新したくない場合それらがcsv値の場合)、ON句をand driving_column1 = 'N'
またはdriving_column1をフィルタリングする外側のクエリにソースサブクエリをラップすることができます(残念なことに、同じクエリ内のアナリティック関数をフィルタ処理できません)。または、マージステートメントの更新セクションにwhere句を追加できます。
いくつかのクイッククエリ。行は常に6つのグループに分かれていますか、それとも変わることができ、最初の行は常に同じ長さですか? – MightyRearranger
行は24行からそれ以上に変更できません。最初の行は常に同じ長さで、最初の3文字は同じです。 – snow