这是一个对 cmets 的长度没有预先假设的解决方案。我添加了两个字符串,一个短(少于 5 个字符)和一个长于 10 个字符,以及一个带有 NULL 注释的字符串,以确保该行不丢失,以彻底测试解决方案。
我假设(empid, dt) 是基表中的唯一组合(可能是主键)。顺便说一句,我希望您实际上并没有在架构中使用 Date 作为列名。
解决方案不包含 WITH 子句;它从 select empid... 开始,可能也不需要 ORDER BY 子句。
with
test_data ( empid, empname, servicenumber, dt, comments ) as (
select 1, 'a', 123, to_date('23-03-1990', 'dd-mm-yyyy'), 'wednesday' from dual union all
select 1, 'a', 1234, to_date('24-04-1990', 'dd-mm-yyyy'), 'Test12' from dual union all
select 2, 'b', 234, to_date('24-05-2016', 'dd-mm-yyyy'), 'Todayis' from dual union all
select 2, 'b', 235, to_date('25-05-2016', 'dd-mm-yyyy'), 'Joe' from dual union all
select 3, 'c', 238, to_date('25-05-2016', 'dd-mm-yyyy'), '' from dual union all
select 4, 'c', 2238, to_date('25-05-2016', 'dd-mm-yyyy'), 'longer string' from dual
)
select empid, empname, servicenumber, dt, level as comno,
substr(comments, 5 * level - 4, 5) as comments
from test_data
connect by level <= 1 + length(comments) / 5
and prior empid = empid
and prior dt = dt
and prior sys_guid() is not null
order by empid, dt
;
EMPID E SERVICENUMBER DT COMNO COMMENTS
---------- - ------------- ---------- ---------- --------------------
1 a 123 1990-03-23 1 wedne
1 a 123 1990-03-23 2 sday
1 a 1234 1990-04-24 1 Test1
1 a 1234 1990-04-24 2 2
2 b 234 2016-05-24 1 Today
2 b 234 2016-05-24 2 is
2 b 235 2016-05-25 1 Joe
3 c 238 2016-05-25 1
4 c 2238 2016-05-25 1 longe
4 c 2238 2016-05-25 2 r str
4 c 2238 2016-05-25 3 ing
新增:如果您的数据是CLOB数据类型,最好使用substr的dbms_lob版本。此外,如果您必须将数据分成 75 个字符段,则必须调整几个数字。这是相同的解决方案,具有这两个更改并且没有 ORDER BY 子句(如果用于将数据迁移到另一个数据库产品则不需要)。注意:dbms_lob.substr() 与通常的substr() 函数相比,“数量”和“偏移量”(第二个和第三个参数)相反;请注意,当您比较解决方案时。
select empid, empname, servicenumber, dt, level as comno,
dbms_lob.substr(comments, 75, 75 * level - 74) as comments
from test_data
connect by level <= 1 + length(comments) / 75
and prior empid = empid
and prior dt = dt
and prior sys_guid() is not null
;