从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 中的正则表达式从逗号分隔列表中删除重复项,但我不想要重复值? [复制]

Oracle如何获取逗号分隔字符串中的出现次数

从excel中的字符串中删除单词的最简单方法是啥?

使用 SQL 。从字符串'HEADER|N1000|E1001|N1002|E1003|N1004|N1005'中提取逗号分隔的数字

从python中的字符串中提取英文单词