【问题标题】:split the regular expression and loop through拆分正则表达式并循环
【发布时间】:2017-07-07 19:06:44
【问题描述】:

我需要在我认为我写的连接内循环。 我正在发布代码。

    select listagg(request_num,',') within group (order by request_num) as request_num,segmentation_name from (
select MST.REQUEST_NUM,seg_dtls.SEGMENT_NAME,LAST_UPDATED_date,seg_dtls.segmentation_name from 
(select  * from rp_sr_master ) Mst,
(select  SUBSTR(ANSWER,1,INSTR (ANSWER, '~', 1)-1) AS SM_ID,sr_id from rp_sR_details 
WHERE Q_ID in (SELECT Q_ID FROM RP_QUESTIONS WHERE field_id='LM_LRE_Q6')
    ) Dtls, (select SM_ID, SQL_STATEMENT, CREATION_DATE, UPDATED_DATE, SEGMENT_NAME,segmentation_name ,TOTAL_COUNT
from rp_sEGMENT_master ) seg_dtls
where Dtls.SM_ID=seg_dtls.SM_ID
and Dtls.sr_id=Mst.sr_id)
group by segmentation_name;

我在这里面临的问题如下,

(select  SUBSTR(ANSWER,1,INSTR (ANSWER, '~', 1)-1) AS SM_ID,sr_id from rp_sR_details 
    WHERE Q_ID in (SELECT Q_ID FROM RP_QUESTIONS WHERE field_id='LM_LRE_Q6')
        )

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

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

它只选择第一个数字 2603,其他数字将被忽略。

有什么方法可以循环遍历“ANSWER”中的所有数字。 我正在寻找想法。

谢谢。

【问题讨论】:

    标签: plsql


    【解决方案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    |
    

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

    【讨论】:

    • 谢谢,我正在努力学习。所以这是我的更多疑问。 '\d+' 查找表达式中的数字。我的情况是,答案就像 345~nas 2016^234~ras2034^the 34_234^help 3. 在这里我尝试了一个 regsub 来查找 ^ 和 ~ 之间的数字,但第一个数字不会有 ^。我试过这个 [0-9]*(?=~) 。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-05
    • 2013-08-11
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多