从oracle中的逗号分隔字符串中提取单词
Posted
技术标签:
【中文标题】从oracle中的逗号分隔字符串中提取单词【英文标题】:Extract words from a comma separated string in oracle 【发布时间】:2015-05-29 06:54:08 【问题描述】:假设我有字符串
Str = 'Aaa,Bbb,Abb,Ccc'
我想把上面的str分成两部分,如下
Str1 = 'Aaa,Abb'
Str2 = 'Bbb,Ccc'
str 中任何以 A 开头的单词都应该放在 str1 中,其余的都放在 str2 中。
如何使用 Oracle 查询来实现这一点?
【问题讨论】:
永远不要将数据存储为逗号分隔的项目。那只会给你带来很多问题。 SQL 不是为此而设计的,而是有单独的行。 @jarlh 评论的补充——您可以使用嵌套表或其他集合类型。 【参考方案1】:str 中以 A 开头的任何单词都应该放在 str1 中,其余的都放在 str2 中。
要在纯 SQL 中实现它,我将使用以下内容:
REGEXP_SUBSTR 列表 SUBSTR 内联视图所以,首先我将使用Split single comma delimited string into rows 此处演示的技术拆分逗号分隔的字符串。
然后,我将使用 LISTAGG 将它们按顺序聚合。
例如,
SQL> WITH
2 t1 AS (
3 SELECT 'Aaa,Bbb,Abb,Ccc' str FROM dual
4 ),
5 t2 AS (
6 SELECT trim(regexp_substr(str, '[^,]+', 1, LEVEL)) str
7 FROM t1
8 CONNECT BY LEVEL <= regexp_count(str, ',')+1
9 ORDER BY str
10 )
11 SELECT
12 (SELECT listagg(str, ',') WITHIN GROUP(
13 ORDER BY NULL) str1
14 FROM t2
15 WHERE SUBSTR(str, 1, 1)='A'
16 ) str1,
17 (SELECT listagg(str, ',') WITHIN GROUP(
18 ORDER BY NULL) str
19 FROM t2
20 WHERE SUBSTR(str, 1, 1)<>'A'
21 ) str2
22 FROM dual
23 /
STR1 STR2
---------- ----------
Aaa,Abb Bbb,Ccc
SQL>
WITH 子句仅用于演示目的,在您的实际场景中,删除 with 子句并直接使用您的表名。虽然使用 WITH 子句看起来很整洁。
【讨论】:
【参考方案2】:使用正则表达式和 ListAg 函数。
注意:从 Oracle 11g 开始提供 LISTAGG 函数!
select listagg(s.name, ',') within group (order by name)
from (select regexp_substr('Aaa,Bbb,Abb,Ccc,Add,Ddd','[^,]+', 1, level) name from dual
connect by regexp_substr('Aaa,Bbb,Abb,Ccc,Add,Ddd', '[^,]+', 1, level) is not null) s
group by decode(substr(name,1,1),'A', 1, 0);
【讨论】:
OP 想要在两个不同的列中。【参考方案3】:此查询在两个不同的行中为您提供所需的输出:
with temp as (select trim (both ',' from 'Aaa,Bbb,Abb,Ccc') as str from dual),
base_table as
( select trim (regexp_substr (t.str,
'[^' || ',' || ']+',
1,
level))
str
from temp t
connect by instr (str,
',',
1,
level - 1) > 0),
ult_table as
(select str,
case upper (substr (str, 1, 1)) when 'A' then 1 else 2 end
as l
from base_table)
select listagg (case when l = 1 then str else null end, ',')
within group (order by str)
str1,
listagg (case when l = 2 then str else null end, ',')
within group (order by str)
str2
from ult_table;
输出
L STR
---------- --------------------------------------------------------------------------------
1 Aaa,Abb
2 Bbb,Ccc
【讨论】:
OP 想要在两个不同的列中。 @LalitKumarB- 感谢您注意到这一点。修改了代码。以上是关于从oracle中的逗号分隔字符串中提取单词的主要内容,如果未能解决你的问题,请参考以下文章
如何在Oracle中的case语句中添加两个用逗号分隔的引号的字符
如何通过 Oracle 中的正则表达式从逗号分隔列表中删除重复项,但我不想要重复值? [复制]
使用 SQL 。从字符串'HEADER|N1000|E1001|N1002|E1003|N1004|N1005'中提取逗号分隔的数字