更新了 Question-Oracle case 语句以提取与单行中的子字符串关联的所有事件的值
Updated Question-Oracle case statement to extract value for all occurance associated with a substring in a single line
我想编写一个 case 语句,它可以从名为 details
的列中提取特定子字符串的值,该列多次出现 [address]
是否可以将 REGEX 与 case 一起使用?
列中的示例数据:
[address]:kattengat 28
[address]:1012 SZ
[address]: Amsterdam
The below SQL only outputs:
kattengat 28
Select case when to_number(instr(details),'[address')>0 then substr(details,REGEXP_INSTR(details,'address',1,1)+8,instr(substr(details,REGEXP_INSTR(details,'address',1,1)+8,'[')-1)) else '' end from table_name;
Expected output is :
kattengat 28 1012 SZ Amsterdam
创建 table 语句:
Create table test (id number(10), details clob);
插入语句:
insert into test (id, details) values (1,to_clob ('[ADDRESS ] kattengat 28
[NAME ] ALEX
[PHONE ] 65438
[ADDRESS ] 1012 SZ
[DOB ] 1st Jan 1998
[ADDRESS ] Amsterdam')):
请注意,我不想连接和添加语句,而是寻找一种解决方案,该解决方案可以根据单个子字符串出现的次数提取与子字符串 [address] 关联的值行
这是一种选择:
SQL> with test (col) as
2 (select '[address]:kattengat 28
3 [address]:1012 SZ
4 [address]: Amsterdam' from dual
5 )
6 select trim(replace(regexp_substr(replace(col, chr(10), '#'), '[^#]+', 1, column_value), '[address]:', '')) result
7 from test cross join
8 table(cast(multiset(select level from dual
9 connect by level <= regexp_count(col, ':')
10 ) as sys.odcinumberlist));
RESULT
--------------------------------------------------------------------------------
kattengat 28
1012 SZ
Amsterdam
SQL>
它有什么作用?
- 第 1 - 5 行 - 样本数据
- 第 6 行:
regexp_substr
部分代码负责将源列值拆分为单独的行
- 它不影响原始值,而是影响换行符 (chr(10)) 被
#
替换(第二个 replace
)的值,并且该字符用作regexp_substr
的分隔符
- 第一个
replace
从源中删除 [address]:
trim
删除 leading/trailing 个空字符串(如“Amsterdam”前面的字符串
- 第 8 - 10 行用于从最终结果中删除重复值(如果源 table 不只包含一行,如我的示例所示)。如果确实如此,那么代码可以稍微简化。
使用您稍后发布的示例数据(顺便说一句,您确定 [NAME] 等前面有空格吗?我想没有!):
SQL> select * from test;
ID DETAILS
---------- --------------------------------------------------
1 [ADDRESS ] kattengat 28
[NAME ] ALEX
[PHONE ] 65438
[ADDRESS ] 1012 SZ
[DOB ] 1st Jan 1998
[ADDRESS ] Amsterdam
我之前贴的代码,稍作修改,因为之前address
是小写,方括号内没有空格,有冒号):
SQL> with temp as
2 (select trim(replace(regexp_substr(replace(details, chr(10), '#'), '[^#]+', 1, column_value), '[ADDRESS ]', '')) result
3 from test cross join
4 table(cast(multiset(select level from dual
5 connect by level <= regexp_count(details, '\[')
6 ) as sys.odcinumberlist))
7 )
8 select *
9 from temp
10 where instr(result, '[') = 0;
RESULT
--------------------------------------------------------------------------------
kattengat 28
1012 SZ
Amsterdam
SQL>
如果您想在一行中获得结果,您可以聚合该查询返回的值作为
SQL> with temp as
2 (select trim(replace(regexp_substr(replace(details, chr(10), '#'), '[^#]+', 1, column_value), '[ADDRESS ]', '')) result,
3 column_value cv
4 from test cross join
5 table(cast(multiset(select level from dual
6 connect by level <= regexp_count(details, '\[')
7 ) as sys.odcinumberlist))
8 )
9 select listagg (result, ', ') within group (order by cv) final_result
10 from temp
11 where instr(result, '[') = 0;
FINAL_RESULT
--------------------------------------------------------------------------------
kattengat 28, 1012 SZ, Amsterdam
SQL>
我想编写一个 case 语句,它可以从名为 details
的列中提取特定子字符串的值,该列多次出现 [address]
是否可以将 REGEX 与 case 一起使用?
列中的示例数据:
[address]:kattengat 28
[address]:1012 SZ
[address]: Amsterdam
The below SQL only outputs:
kattengat 28
Select case when to_number(instr(details),'[address')>0 then substr(details,REGEXP_INSTR(details,'address',1,1)+8,instr(substr(details,REGEXP_INSTR(details,'address',1,1)+8,'[')-1)) else '' end from table_name;
Expected output is :
kattengat 28 1012 SZ Amsterdam
创建 table 语句:
Create table test (id number(10), details clob);
插入语句:
insert into test (id, details) values (1,to_clob ('[ADDRESS ] kattengat 28
[NAME ] ALEX
[PHONE ] 65438
[ADDRESS ] 1012 SZ
[DOB ] 1st Jan 1998
[ADDRESS ] Amsterdam')):
请注意,我不想连接和添加语句,而是寻找一种解决方案,该解决方案可以根据单个子字符串出现的次数提取与子字符串 [address] 关联的值行
这是一种选择:
SQL> with test (col) as
2 (select '[address]:kattengat 28
3 [address]:1012 SZ
4 [address]: Amsterdam' from dual
5 )
6 select trim(replace(regexp_substr(replace(col, chr(10), '#'), '[^#]+', 1, column_value), '[address]:', '')) result
7 from test cross join
8 table(cast(multiset(select level from dual
9 connect by level <= regexp_count(col, ':')
10 ) as sys.odcinumberlist));
RESULT
--------------------------------------------------------------------------------
kattengat 28
1012 SZ
Amsterdam
SQL>
它有什么作用?
- 第 1 - 5 行 - 样本数据
- 第 6 行:
regexp_substr
部分代码负责将源列值拆分为单独的行- 它不影响原始值,而是影响换行符 (chr(10)) 被
#
替换(第二个replace
)的值,并且该字符用作regexp_substr
的分隔符
- 第一个
replace
从源中删除[address]:
trim
删除 leading/trailing 个空字符串(如“Amsterdam”前面的字符串- 第 8 - 10 行用于从最终结果中删除重复值(如果源 table 不只包含一行,如我的示例所示)。如果确实如此,那么代码可以稍微简化。
使用您稍后发布的示例数据(顺便说一句,您确定 [NAME] 等前面有空格吗?我想没有!):
SQL> select * from test;
ID DETAILS
---------- --------------------------------------------------
1 [ADDRESS ] kattengat 28
[NAME ] ALEX
[PHONE ] 65438
[ADDRESS ] 1012 SZ
[DOB ] 1st Jan 1998
[ADDRESS ] Amsterdam
我之前贴的代码,稍作修改,因为之前address
是小写,方括号内没有空格,有冒号):
SQL> with temp as
2 (select trim(replace(regexp_substr(replace(details, chr(10), '#'), '[^#]+', 1, column_value), '[ADDRESS ]', '')) result
3 from test cross join
4 table(cast(multiset(select level from dual
5 connect by level <= regexp_count(details, '\[')
6 ) as sys.odcinumberlist))
7 )
8 select *
9 from temp
10 where instr(result, '[') = 0;
RESULT
--------------------------------------------------------------------------------
kattengat 28
1012 SZ
Amsterdam
SQL>
如果您想在一行中获得结果,您可以聚合该查询返回的值作为
SQL> with temp as
2 (select trim(replace(regexp_substr(replace(details, chr(10), '#'), '[^#]+', 1, column_value), '[ADDRESS ]', '')) result,
3 column_value cv
4 from test cross join
5 table(cast(multiset(select level from dual
6 connect by level <= regexp_count(details, '\[')
7 ) as sys.odcinumberlist))
8 )
9 select listagg (result, ', ') within group (order by cv) final_result
10 from temp
11 where instr(result, '[') = 0;
FINAL_RESULT
--------------------------------------------------------------------------------
kattengat 28, 1012 SZ, Amsterdam
SQL>