再帰サブクエリ ファクタリング (再帰 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;
あなたのデータを使用すると、次のことが得られます。
LINE PART_ADDRESS
---------- ----------------------------------------
1 152 Main st North Pole Factory 44, near
2 the rear entrance cross the street and
3 turn left and keep walking straight.
2 つのアドレスを使用したSQL Fiddle デモ。
これらの部分的な値を列に変換することもできます。これは、たとえばビューとしての最終目標だと思います。
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;
別の SQL Fiddle。
street_address
長さが 120 文字に近づくと、3 つの 40 文字ブロックにうまく収まらない可能性があることに注意してください。次の「行」にラップされる単語の長さに応じて、いくつかの文字が失われます。このアプローチでは 3 行以上が生成されますが、ビューは最初の 3 行しか使用しないため、アドレスの末尾が失われる可能性があります。フィールドを長くしたり、address_4
そのような状況に備えたいと思うかもしれません...