我有一个包含2个多值字段的表 例如:
第一行包含以下字段:
字段1:1、4、5
字段2:1、2、3
第二行包含:
字段1:5、6、7
字段2:,6,3
第三行:
字段1:8,,9
字段2:1、3,
|---------------------|------------------|
| column 1 | column 2 |
|---------------------|------------------|
| 1,4,5 | 1,2,3 |
|---------------------|------------------|
| 5,6,7 | ,6,3 |
|---------------------|------------------|
| 8,,9 | 1,,3 |
|---------------------|------------------|
因此两个字段都相关-字段1位置2的值与字段2位置2的值有关。 我要做的是仅在每个组中的值相等的情况下更新/替换字段2中的一个或多个值。
例如 在第一行中,位置0处具有匹配值'1',需要在字段2中进行替换。我该怎么做?只需提及字段1和字段2中的空值不应视为相等,它们只是在显示位置。询问您是否需要更多信息
答案 0 :(得分:0)
首先,不要使用它;而是将表格设计固定为不存储逗号分隔的值。但是,如果您坚持要求,则可以使用此方法将csv拆分为单个值,然后执行替换,然后再次对其进行汇总,并使用Body
语句来更新与MERGE
伪列上的更新相关的表
Oracle设置:
ROWID
执行替换:
这会将每个CREATE TABLE test_data ( column1 VARCHAR2(20), column2 VARCHAR2(20) );
INSERT INTO test_data ( column1, column2 )
SELECT '1,4,5', '1,2,3' FROM DUAL UNION ALL
SELECT '5,6,7', ',6,3' FROM DUAL UNION ALL
SELECT '8,,9', '1,,3' FROM DUAL UNION ALL
SELECT '1,4,5', '3,4,5' FROM DUAL;
匹配column2
的值加10。
column1
输出:
MERGE INTO test_data dst
USING (
SELECT rid,
REPLACE(
LISTAGG(
COALESCE( TO_CHAR( column1 ), '#' ),
','
) WITHIN GROUP ( ORDER BY idx ),
'#'
)AS column1,
REPLACE(
LISTAGG(
COALESCE( TO_CHAR( CASE column2 WHEN column1 THEN column2 + 10 ELSE column2 END ), '#' ),
','
) WITHIN GROUP ( ORDER BY idx ),
'#'
) AS column2
FROM (
SELECT t.ROWID AS rid,
COLUMN_VALUE AS idx,
TO_NUMBER( REGEXP_SUBSTR( t.column1, '(\d*)(,|$)', 1, COLUMN_VALUE, NULL, 1 ) ) AS column1,
TO_NUMBER( REGEXP_SUBSTR( t.column2, '(\d*)(,|$)', 1, COLUMN_VALUE, NULL, 1 ) ) AS column2
FROM test_data t
CROSS JOIN
TABLE(
CAST(
MULTISET(
SELECT LEVEL
FROM DUAL
CONNECT BY LEVEL < REGEXP_COUNT( t.column1, '(\d*)(,|$)' )
)
AS SYS.ODCINUMBERLIST
)
) l
)
GROUP BY rid
) src
ON ( dst.ROWID = src.RID )
WHEN MATCHED THEN
UPDATE SET column2 = src.column2 WHERE src.column2 <> dst.column2;
COLUMN1 | COLUMN2 :------ | :------ 1,4,5 | 11,2,3 5,6,7 | ,16,3 8,,9 | 1,,3 1,4,5 | 3,14,15
db <>提琴here