用定界符在SQL中循环

时间:2019-05-24 10:03:30

标签: sql regex oracle regexp-substr

我只是想知道如何在sql中循环?

例如 我有此专栏

PARAMETER_VALUE  E,C;S,C;I,X;G,T;S,J;S,F;C,S;

我想将(,)之前的所有值存储在temp列中,也希望将(;)之后的所有值存储在另一列中 然后它会停止,直到(;)之后没有更多的价值为止。

示例的预期输出

COL1 E S I G S S C

COL2 C C X T J F S

等。 。

2 个答案:

答案 0 :(得分:2)

您可以将regexp_substr()窗口分析函数与connect by level <=子句一起使用

with t1(PARAMETER_VALUE) as
(
 select 'E,C;S,C;I,X;G,T;S,J;S,F;C,S;' from dual
), t2 as
( 
select level as rn,
       regexp_substr(PARAMETER_VALUE,'([^,]+)',1,level) as str1,
       regexp_substr(PARAMETER_VALUE,'([^;]+)',1,level) as str2
  from t1
connect by level <= regexp_count(PARAMETER_VALUE,';') 
)
select listagg( regexp_substr(str1,'([^;]+$)') ,' ') within group (order by rn) as col1,
       listagg( regexp_substr(str2,'([^,]+$)') ,' ') within group (order by rn) as col2 
  from t2;

COL1            COL2
-------------   -------------
E S I G S S C   C C X T J F S

Demo

答案 1 :(得分:1)

假设您需要将输入分为;分隔符的行,然后分成,分隔符的列,则可以执行以下操作:

-- WITH clause included to simulate input data. Not part of the solution;
-- use actual table and column names in the SELECT statement below.
with 
  t1(id, parameter_value) as (
    select 1, 'E,C;S,C;I,X;G,T;S,J;S,F;C,S;' from dual union all
    select 2, ',U;,;V,V;'                    from dual union all
    select 3, null                           from dual
  )
-- End of simulated input data
select  id,
        level as ord,
        regexp_substr(parameter_value, '(;|^)([^,]*),', 1, level, null, 2) as col1,
        regexp_substr(parameter_value, ',([^;]*);'    , 1, level, null, 1) as col2
from    t1
connect by  level <= regexp_count(parameter_value, ';') 
        and id = prior id 
        and prior sys_guid() is not null
order   by id, ord
;

 ID ORD COL1 COL2
--- --- ---- ----
  1   1 E    C   
  1   2 S    C   
  1   3 I    X   
  1   4 G    T   
  1   5 S    J   
  1   6 S    F   
  1   7 C    S   
  2   1      U   
  2   2          
  2   3 V    V   
  3   1         

注意-这不是分割输入的最有效方法(没有什么效率很高-原因是违反了“第一范式”的数据模型)。可以使用标准instrsubstr对此进行改进,但是查询将更加复杂,因此难以维护。

我生成了更多的输入数据,以说明一些事情。您可能有多个输入必须同时分解。必须谨慎行事。 (请注意CONNECT BY中的其他条件)。我还说明了NULL的处理-如果逗号在分号后,则表示该对中的“第1列”部分必须为NULL。显示在输出中。