在Oracle中,我有一个表,我需要将其字段之一分成几行。问题是没有确切的分隔符,我只知道属性的值格式是什么。
NumberVarchar 团结
示例如下。
objectid linkvalue
1 1V 2E 3T/B
2 3C+1E. 3V
3 5V.4PH
4 V H
5 V H 8V
我需要输出类似于以下内容将其插入到另一个表中:
objectid linkvalue
1 1V
1 2E
1 3T/B
2 3C
2 1E
2 3V
3 5V
3 4PH
4 V H
5 V H
5 8V
任何想法或建议该怎么做?预先非常感谢
答案 0 :(得分:2)
这是另一种方式:
with tbl(objectid, linkvalue) as (
select 1, '1V 2E 3T/B' from dual union all
select 2, '3C+1E. 3V' from dual union all
select 3, '5V.4PH' from dual
)
select objectid,
regexp_substr(linkvalue, '(.*?)([ +.]+|$)', 1, level, NULL, 1)
from tbl
connect by level <= regexp_count(linkvalue, '[ +.]+') + 1
and prior objectid = objectid
and prior sys_guid() is not null;
OBJECTID REGEXP_SUBSTR(LINKVALUE,'(.*?)([ +.]+|$)',1,LEVEL,NULL,1)
-------- ----------------------------------------------------------
1 1V
1 2E
1 3T/B
2 3C
2 1E
2 3V
3 5V
3 4PH
编辑:添加了没有分隔符的情况。通过以在大写字母和数字之间添加空格。当然有点脏,但我不告诉你是否不会。
Edit2:允许使用由一个或多个定界符分隔的多个单个大写字母组成的值。正则表达式越来越难看。
-- Set up data set
with tbl(objectid, linkvalue) as (
select 1, '1V 2E 3T/B' from dual union all
select 2, '3C+1E. 3V' from dual union all
select 3, '5V.4PH' from dual union all
select 4, '4H6C' from dual union all
select 5, 'C E O 8V' from dual union all
select 6, 'V H' from dual union all
select 7, '9X X Y Z' from dual
),
-- Add a delimiter where missing
tbl1(objectid, linkvalue) as (
select objectid,
regexp_replace(linkvalue, '([A-Z])([0-9])', '\1 \2')
from tbl
)
select objectid,
regexp_substr(linkvalue, '(([A-Z][ +.]?)+|.*?)([ +.]+|$)', 1, level, NULL, 1)
from tbl1
connect by regexp_substr(linkvalue, '(([A-Z][ +.]?)+|.*?)([ +.]+|$)', 1, level) is not null
and prior objectid = objectid
and prior sys_guid() is not null;
答案 1 :(得分:1)
如果分隔符可以是.
或+
或,则此查询有效:
select distinct objectid,regexp_substr(linkvalue,'[^+|.| ]+', 1, level) txt
from ( select 1 objectid, '1V 2E 3T/B' linkvalue from dual
union all select 2 , '3C+1E. 3V' from dual
union all select 3, '5V.4PH' from dual)
connect by regexp_substr(linkvalue, '[^+|.| ]+', 1, level) is not null
order by 1
答案 2 :(得分:-3)
将所有换行符替换为普通的换行符(在下面的情况下,我使用空格)。然后进行交叉联接并过滤掉所有空白值。
declare @data table(id int, codes varchar(50))
insert into @data values
(1, '1V 2E 3T/B'),
(2, '3C+1E. 3V'),
(3, '5V4PH')
select id, value
from (select id, replace(replace(replace(codes, 'V', 'V '), '+', ' '), '.', ' ') [codes]
from @data) d
cross apply string_split(d.codes, ' ')
where value <> ''