You can use recursive subquery factoring (recursive CTE):
with s (street_address, line, part_address, remaining) as ( select street_address, 0 as line, null as part_address, street_address as remaining from address union all select street_address, line + 1 as line, case when length(remaining) <= 40 then remaining else substr(remaining, 1, instr(substr(remaining, 1, 40), ' ', -1, 1)) end as part_address, case when length(remaining) <= 40 then null else substr(remaining, instr(substr(remaining, 1, 40), ' ', -1, 1) + 1) end as remaining from s ) cycle remaining set is_cycle to 'Y' default 'N' select line, part_address from s where part_address is not null order by street_address, line;
What with your data gives:
LINE PART_ADDRESS
SQL Fiddle demo with two addresses.
You can also convert these partial values ββto columns, which I think is your final goal, for example. as a view:
create or replace view v_address as with cte (street_address, line, part_address, remaining) as ( select street_address, 0 as line, null as part_address, street_address as remaining from address union all select street_address, line + 1 as line, case when length(remaining) <= 40 then remaining else substr(remaining, 1, instr(substr(remaining, 1, 40), ' ', -1, 1)) end as part_address, case when length(remaining) <= 40 then null else substr(remaining, instr(substr(remaining, 1, 40), ' ', -1, 1) + 1) end as remaining from cte ) cycle remaining set is_cycle to 'Y' default 'N' select street_address, cast (max(case when line = 1 then part_address end) as varchar2(40)) as address_1, cast (max(case when line = 2 then part_address end) as varchar2(40)) as address_2, cast (max(case when line = 3 then part_address end) as varchar2(40)) as address_3 from cte where part_address is not null group by street_address;
Another SQL script .
It may be worth noting that if the length of street_address approaches 120 characters, it may not fit neatly into 3 40-char blocks - you lose some characters depending on the length of the word enclosed in the next 'line'. This approach will generate more than 3 lines, but the view uses only the first three, so you may lose the end of the address. You might want the fields to be longer or have address_4 for these situations ...