은 재귀 서브 쿼리 인수를 사용하여 두 가지 방법
- 브 루트 포스가 있습니다.
- Lee는 모델 절 + 반복을 사용합니다. https://en.wikipedia.org/wiki/Lee_algorithm
업데이트. 첫 번째 접근 방식의 빠른 데모.
column str format a30
with t(y, str) as
( select 1, '00 000 e000000' from dual
union all select 2, ' 0 ' from dual
union all select 3, '0000 000 0 00000 ' from dual
union all select 4, ' 0 0 0 ' from dual
union all select 5, 's0 000 000 00000 ' from dual
union all select 6, ' 0 ' from dual)
, matrix as
(select x, y, str, substr(str, x, 1) z, rownum id
from t
cross join (select rownum x from dual connect by level <= 17))
, rec(x,y,z,id_list) as
(select x, y, z, cast(id as varchar2(4000)) from matrix where z = 's'
union all
select m.x, m.y, m.z, r.id_list || '|' || m.id
from matrix m
join rec r on (r.x + 1 = m.x and r.y = m.y
or r.x - 1 = m.x and r.y = m.y
or r.x = m.x and r.y + 1 = m.y
or r.x = m.x and r.y - 1 = m.y)
and instr('|' || r.id_list || '|', '|' || m.id || '|') = 0
and m.z != '0'
and r.z = any ('s', ' ')
)
, route as
(select regexp_substr(x, '\d+', 1, rownum) mark
from
(select max(id_list) keep
(dense_rank first order by regexp_count(id_list,'|')) x
from rec
where z = 'e')
connect by level <= regexp_count(x,'|'))
select y, listagg(decode(z, ' ', nvl2(mark, '=', z), z))
within group (order by x) str
from matrix
left join route on id = mark
group by y
order by y;
Y STR
---------- ------------------------------
1 00 000 e000000
2 0=
3 0000 000 0=00000
4 ===0 0 =0
5 s0=000 000=00000
6 0=========
6 rows selected.
모델 솔루션은 훨씬 더 효율적이지만, SQL 어쨌든이 특정 작업을 해결하는 가장 좋은 방법은 아닙니다.
SQL은 주로 RDBMS의 데이터를 관리하기위한 것이지 네트워킹 규칙, 그래프 및 미로 해결 등을 위해 설계되지 않았습니다. –
나는 이것을 알고 있지만 SQL에서이 작업을 해결해야합니다. – sleekmonk