我只是想知道如何在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
等。 。
答案 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
答案 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
注意-这不是分割输入的最有效方法(没有什么效率很高-原因是违反了“第一范式”的数据模型)。可以使用标准instr
和substr
对此进行改进,但是查询将更加复杂,因此难以维护。
我生成了更多的输入数据,以说明一些事情。您可能有多个输入必须同时分解。必须谨慎行事。 (请注意CONNECT BY中的其他条件)。我还说明了NULL的处理-如果逗号在分号后,则表示该对中的“第1列”部分必须为NULL。显示在输出中。