【问题标题】:looping in sql with delimiter使用分隔符在 sql 中循环
【发布时间】:2019-05-24 10:03:30
【问题描述】:

我刚刚想到如何在 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

等等。 . .

【问题讨论】:

  • 更改您的数据模型/设计。不同的值应该通过将它们存储为单独的列来表示,而不是混杂在一起成为带有分隔符的字符串。因此,您将继续面临问题,这从 SO 中与您类似的大量问题中可以看出。
  • 我不明白。您是否希望结果有两列和一个行,其值为'E S I G S S C''C C X T J F S'(由空格分隔的字母字符串)?或者您是否希望输出具有两列和 行,并且每个值(每个行/列交叉点)只有一个字母?只有后者才有意义 - 如果是前者,我想知道你为什么要首先这样做。

标签: sql regex oracle regexp-substr


【解决方案1】:

你可以通过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

【讨论】:

    【解决方案2】:

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

    -- 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。这显示在输出中。

    【讨论】:

    • 嗨@mathguy,如果我只有逗号分隔值怎么办?然后每个值转到单独的列。比如 ='E,C,G,SMS' 然后第 1 列 = E,第 2 列 = C 等等。
    • @JeannellCasaje - 这是一个不同的问题(尽管它可能看起来与您相似);如果您有不同的问题,请将其发布在新线程中。随意参考这个线程,虽然这可能不是太重要,因为问题确实不同(当您使用相同的分隔符来标记行结束和列分隔时)。
    猜你喜欢
    • 1970-01-01
    • 2014-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多