Oracle 一行字符串拆分为多行

测试数据

--单条数据
with z_branch as(
  select 'BR1001' brid, 'BR1001.BR1002.BR1003' br_level from dual
)
select * from z_branch;

在这里插入图片描述

--多条数据
with z_branch as(
  select 'BR1001' brid, 'BR1001.BR1002.BR1003' br_level from dual
  union all
  select 'BR1002' brid, 'BR1002.BR1003' br_level from dual
  union all
  select 'BR1003' brid, 'BR1001.BR1003' br_level from dual
)
select * from z_branch;

在这里插入图片描述

1. 单个字符串或单条数据拆分

如果表中只有单行数据或拆分单个字符串,可以使用。网上大部分讲的都是单条数据的拆分,如果是多条数据拆分则不适用。

with z_branch as(
  select 'BR1001' brid, 'BR1001.BR1002.BR1003' br_level from dual
)
select level, 
       regexp_count(br_level, '\.') + 1,
       regexp_substr(br_level, '[^.]+', 1, level) s_brid
  from z_branch t
connect by level <= regexp_count(br_level, '\.') + 1;

regexp_count(br_level, ‘.’) 统计字符.的个数
regexp_substr(br_level, ‘[^.]+’, 1, level) br_level字段从位置1开始使用字符.拆分,level指取拆分后第level个字符串

with z_branch as(
  select 'BR1001' brid, 'BR1001.BR1002.BR1003' br_level from dual
)
select level,
       length(brid) - length(replace(brid, '.', '')) + 1,
       regexp_substr(br_level, '[^.]+', 1, level) s_brid
  from z_branch t
connect by level <= length(br_level) - length(replace(br_level, '.', '')) + 1;

在这里插入图片描述
错误示例

--结果不符合预期
with z_branch as(
  select 'BR1001' brid, 'BR1001.BR1002.BR1003' br_level from dual
  union all
  select 'BR1002' brid, 'BR1002.BR1003' br_level from dual
  union all
  select 'BR1003' brid, 'BR1001.BR1003' br_level from dual
)
select brid,
       level, 
       regexp_count(br_level, '\.') + 1,
       regexp_substr(br_level, '[^.]+', 1, level) s_brid
  from z_branch t
connect by level <= regexp_count(br_level, '\.') + 1;

在这里插入图片描述

-- 不符合预期
with z_branch as(
  select 'BR1001' brid, 'BR1001.BR1002.BR1003' br_level from dual
  union all
  select 'BR1002' brid, 'BR1002.BR1003' br_level from dual
  union all
  select 'BR1003' brid, 'BR1001.BR1003' br_level from dual
)
select brid,
       level, 
       regexp_count(br_level, '\.') + 1,
       regexp_substr(br_level, '[^.]+', 1, level) s_brid
  from z_branch t
 where t.brid = 'BR1001'
connect by level <= regexp_count(br_level, '\.') + 1;

在这里插入图片描述
从此结果可知数据是先生成后,然后使用where条件筛选

2. 多条数据拆分

1、方法1
--正确
with z_branch as(
  select 'BR1001' brid, 'BR1001.BR1002.BR1003' br_level from dual
  union all
  select 'BR1002' brid, 'BR1002.BR1003' br_level from dual
  union all
  select 'BR1003' brid, 'BR1001.BR1003' br_level from dual
)
select brid,
       level, 
       regexp_count(br_level, '\.') + 1 as row_cnt,
       regexp_substr(br_level, '[^.]+', 1, level) as s_brid
  from z_branch t
connect by level <= regexp_count(br_level, '\.') + 1
   and t.brid = prior t.brid
   and prior dbms_random.value > 0;

在这里插入图片描述

2、方法2
--正确 借助伪列
with z_branch as(
  select 'BR1001' brid, 'BR1001.BR1002.BR1003' br_level from dual
  union all
  select 'BR1002' brid, 'BR1002.BR1003' br_level from dual
  union all
  select 'BR1003' brid, 'BR1001.BR1003' br_level from dual
),
z_level as(
  select level lv from dual connect by level < 10
) 
select t.brid,
       a.lv, 
       regexp_count(t.br_level, '\.') + 1 as row_cnt,
       regexp_substr(t.br_level, '[^.]+', 1, a.lv) as s_brid
  from z_branch t
 inner join z_level a
    on a.lv <= regexp_count(t.br_level, '\.') + 1;

在这里插入图片描述
注意:创建的伪列行数,要大于其中字符串拆分后数量最大值,本示例中字符串拆分后最大值是3,所以只要伪列行数大于3即可。

  • 14
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值