Oracle:SQL 用另一个字符串的项目替换一个字符串中的项目
Oracle : SQL to replace items in a string with items of another string
我有一列 "col1" 值如下:'a,b,x,y,z'(有序字符串)
另一列 "col2" 类似于:'a,x' 或 'b,y,z'(有序字符串)
"col2"中的所有字符串值都是由子查询生成的。所以它不是恒定的。
但是,"col1"中的值是常数。即 col1='a,b,x,y,z'
create table test (col1 varchar2(20), col2 varchar2(10));
insert into test values ('a,b,x,y,z','a,x');
insert into test values ('a,b,x,y,z','b,y,z');
需要帮助进行一次更换 sql。
需要帮助将 "col1" 上的元素替换为 "col2"。
例如,
when col2='a,x', the result should be : 'b,y,z'
when col2='b,y,z', the result should be : 'a,x'
这是一种选择;我包含了 ID 列以使其更简单。我希望在你的 真实 案例中存在类似的专栏。
想法是:
- 将每列 (
col1
, col2
) 拆分为行
- CTE
one
表示 col1
的行
- CTE
two
表示 col2
的行
- 使用
MINUS
集合运算符,减去这两组行
- 使用
LISTAGG
,聚合结果
SQL> select * From test;
ID COL1 COL2
---------- -------------------- ----------
1 a,b,x,y,z a,x
2 a,b,x,y,z b,y,z
SQL> with
2 one as
3 (select id, regexp_substr(col1, '[^,]+', 1, column_value) col
4 from test,
5 table(cast(multiset(select level from dual
6 connect by level <= regexp_count(col1, ',') + 1
7 ) as sys.odcinumberlist))
8 ),
9 two as
10 (select id, regexp_substr(col2, '[^,]+', 1, column_value) col
11 from test,
12 table(cast(multiset(select level from dual
13 connect by level <= regexp_count(col2, ',') + 1
14 ) as sys.odcinumberlist))
15 ),
16 t_minus as
17 (select id, col from one
18 minus
19 select id, col from two
20 )
21 select id, listagg(col, ',') within group (order by col) result
22 From t_minus
23 group by id;
ID RESULT
---------- --------------------
1 b,y,z
2 a,x
SQL>
这是一个有趣的方法:
select col1, col2,
ltrim(regexp_replace(translate(replace(col1,','),','||replace(col2,','),',')
,'(.)',','),',') as col3
from test;
即:(从内到外读取执行的函数调用)
- 从两个字符串中删除逗号
- 使用 TRANSLATE() 从第一个字符串中删除第二个字符串的字符
- 使用REGEXP_REPLACE在剩余字符串的每个字符前添加逗号
- Trim 前导逗号
我有一列 "col1" 值如下:'a,b,x,y,z'(有序字符串)
另一列 "col2" 类似于:'a,x' 或 'b,y,z'(有序字符串)
"col2"中的所有字符串值都是由子查询生成的。所以它不是恒定的。
但是,"col1"中的值是常数。即 col1='a,b,x,y,z'
create table test (col1 varchar2(20), col2 varchar2(10));
insert into test values ('a,b,x,y,z','a,x');
insert into test values ('a,b,x,y,z','b,y,z');
需要帮助进行一次更换 sql。
需要帮助将 "col1" 上的元素替换为 "col2"。
例如,
when col2='a,x', the result should be : 'b,y,z'
when col2='b,y,z', the result should be : 'a,x'
这是一种选择;我包含了 ID 列以使其更简单。我希望在你的 真实 案例中存在类似的专栏。
想法是:
- 将每列 (
col1
,col2
) 拆分为行- CTE
one
表示col1
的行 - CTE
two
表示col2
的行
- CTE
- 使用
MINUS
集合运算符,减去这两组行 - 使用
LISTAGG
,聚合结果
SQL> select * From test;
ID COL1 COL2
---------- -------------------- ----------
1 a,b,x,y,z a,x
2 a,b,x,y,z b,y,z
SQL> with
2 one as
3 (select id, regexp_substr(col1, '[^,]+', 1, column_value) col
4 from test,
5 table(cast(multiset(select level from dual
6 connect by level <= regexp_count(col1, ',') + 1
7 ) as sys.odcinumberlist))
8 ),
9 two as
10 (select id, regexp_substr(col2, '[^,]+', 1, column_value) col
11 from test,
12 table(cast(multiset(select level from dual
13 connect by level <= regexp_count(col2, ',') + 1
14 ) as sys.odcinumberlist))
15 ),
16 t_minus as
17 (select id, col from one
18 minus
19 select id, col from two
20 )
21 select id, listagg(col, ',') within group (order by col) result
22 From t_minus
23 group by id;
ID RESULT
---------- --------------------
1 b,y,z
2 a,x
SQL>
这是一个有趣的方法:
select col1, col2,
ltrim(regexp_replace(translate(replace(col1,','),','||replace(col2,','),',')
,'(.)',','),',') as col3
from test;
即:(从内到外读取执行的函数调用)
- 从两个字符串中删除逗号
- 使用 TRANSLATE() 从第一个字符串中删除第二个字符串的字符
- 使用REGEXP_REPLACE在剩余字符串的每个字符前添加逗号
- Trim 前导逗号