使用定界符循环 sql

looping in sql with delimiter

我刚想到如何循环 sql?

例如 我有这个专栏

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

我想将 (,) 之前的所有值存储在临时列中,并将 (;) 之后的所有值存储到另一列中 然后它不会停止,直到 (;)

之后没有更多的值

示例的预期输出

COL1 E S I G S S C

COL2 C C X T J F S

等。 . .

你可以通过使用 regexp_substr() window 带有 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

假设您需要在 ; 分隔符处将输入分隔成行,然后在 , 分隔符处分隔成列,您可以这样做:

-- 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 的处理——如果逗号紧跟在分号之后,这意味着该对的 "column 1" 部分必须为 NULL。这显示在输出中。