拆分正则表达式并循环遍历

时间:2017-02-18 06:10:43

标签: plsql

我需要在一个连接中循环,这是我认为我写的。 我发布了代码。

2603~NG non IaaS  IT Professional^2600~NG non IaaS Senior IT^2598~NG data profiling SENIOR IT professional^2595~Nigeria data profiling IT professiona

我面临的问题如下:

{{1}}

在上面的代码中,答案将是这样的:

{{1}}

它只选择第一个数字2603而其他数字将被遗漏。

有没有什么方法可以循环查看“答案”中的所有数字。 我在寻找想法。

感谢。

1 个答案:

答案 0 :(得分:1)

一个想法是使用一种方法将逗号分隔的字符串拆分成行,您可以在以下答案中找到此方法的示例:

Splitting comma separated values in Oracle

How can I use regex to split a string, using a string as a delimiter?

上述解决方案使用regexp_substr功能 如果你深入研究Oracle REGEXP_SUBSTR function的细节,你会发现那里有可选的position参数。

此参数可与本答案中显示的结果组合:
SQL to generate a list of numbers from 1 to 100
(即SELECT LEVEL n FROM DUAL CONNECT BY LEVEL <= 100)以下方式:

with xx as (
select '2603~NG non IaaS  IT Professional^2600~NG non IaaS Senior '
       || 'IT^2598~NG data profiling SENIOR IT professional^2595~Nigeria '
       || 'data profiling IT professiona' as answer
from dual
)
select LEVEL AS n, regexp_substr( answer, '\d+',  1, level) as nbr
from xx
connect by level <= 6
;

以上查询产生以下结果:

N |NBR  |
--|-----|
1 |2603 |
2 |2600 |
3 |2598 |
4 |2595 |
5 |     |
6 |     |

我们需要的是从结果集中消除空值,可以使用简单的条件IS NOT NULL

来完成
with xx as (
select '2603~NG non IaaS  IT Professional^2600~NG non IaaS Senior '
       || 'IT^2598~NG data profiling SENIOR IT professional^2595~Nigeria '
       || 'data profiling IT professiona' as answer
from dual
)
select LEVEL AS n, regexp_substr( answer, '\d+',  1, level) as nbr
from xx
connect by regexp_substr( answer, '\d+',  1, level) IS NOT NULL
;

N |NBR  |
--|-----|
1 |2603 |
2 |2600 |
3 |2598 |
4 |2595 |

上述查询适用于单个记录,但在我们尝试解析2行或更多行时会感到困惑。幸运的是,SO的另一个答案有助于解决这个问题:

Is there any alternative for OUTER APPLY in Oracle?

--  source data
WITH xx as (
select 1 AS id,
       '2603~NG non IaaS  IT Professional^2600~NG non IaaS Senior '
       || 'IT^2598~NG data profiling SENIOR IT professional^2595~Nigeria '
       || 'data profiling IT professiona' as answer
from dual
UNION ALL
select 2 AS id,
       '11111~NG non IaaS  IT Professional^22222~NG non IaaS Senior '
       || 'IT^2598~NG data 33333 profiling SENIOR IT professional^44~Nigeria '
       || 'data profiling 5 IT professiona 66' as answer
from dual
)
-- end of source data


SELECT t.ID, t1.n, t1.nbr
FROM xx t
CROSS JOIN LATERAL (
        select LEVEL AS n, regexp_substr( t.answer, '\d+',  1, level) as nbr
        from dual
        connect by regexp_substr( t.answer, '\d+',  1, level) IS NOT NULL
) t1;

上述查询从两个记录中解析数字,然后以下列形式显示:

ID |N |NBR   |
---|--|------|
1  |1 |2603  |
1  |2 |2600  |
1  |3 |2598  |
1  |4 |2595  |
2  |1 |11111 |
2  |2 |22222 |
2  |3 |2598  |
2  |4 |33333 |
2  |5 |44    |
2  |6 |5     |
2  |7 |66    |

我相信你会设法将这个简单的“解析”查询合并到你的主查询中。