2011-08-02 8 views
6

복잡한 요구 사항이 있다고 생각합니다.오라클 - 문자열 조합 순열

오라클 10.2를 사용하여 결합 순열을 수행 했으므로 데카르트 조인을 사용하여이를 해결할 수 있었지만 가장 단순하고 유연한 개선이 필요하다고 생각합니다.

주요 동작입니다.

입력 문자열 : '하나 둘'

출력 : '이' '하나 둘' '이 하나의'내 솔루션에 대한

내가 제한 한 '하나' 문자열의 수는 5입니다 (결과는 계승 근처의 숫자 임).

SQL :

with My_Input_String as (select 1 as str_id, 'alpha beta omega gama' as str from dual) 

--------logic------- 

, String_Parse as (
        SELECT REGEXP_SUBSTR(str, '[^ ]+', 1, ROWNUM) str 
        FROM My_Input_String 
        where rownum < 6 -- string limitation -- 
        CONNECT BY level <= LENGTH(REGEXP_REPLACE(str, '([^ ])+|.', '\1')) 
       )  

--------CRAP select need refactoring------- 

select str from String_Parse 
union 
select REGEXP_REPLACE(trim(s1.str||' '||s2.str||' '||s3.str||' '||s4.str||' '||s5.str), '(){2,}', ' ') as str 
from 

(select str from String_Parse union select ' ' from dual) s1, 
(select str from String_Parse union select ' ' from dual) s2, 
(select str from String_Parse union select ' ' from dual) s3, 
(select str from String_Parse union select ' ' from dual) s4, 
(select str from String_Parse union select '  ' from dual) s5 
where 
-- 
s1.str <> s2.str and s1.str <> s3.str and s1.str <> s4.str and s1.str <> s5.str 
-- 
and s2.str <> s3.str and s2.str <> s4.str and s2.str <> s5.str 
-- 
and s3.str <> s4.str and s3.str <> s5.str 
-- 
and s4.str <> s5.str 
+2

SQL에 있어야합니까 아니면 plsql을 사용할 수 있습니까? – Rene

+1

고정 된 수의 문자열 요소가 있습니까? 변수가 다를 수 있다면 PL/SQL 라우트를 피하는 방법을 알 수 없습니다. "유연한"이라는 단어를 사용하면 그것이 당신이 생각하는 것임을 암시합니다. – APC

+0

예, plsql을 사용하여 수행 할 수 있습니다. 문자열 요소의 수와 관련하여 – Metl

답변

8

편집 : 일반적인 것을 얻었습니다. 결국 간단하게 (그러나 거기에 도착하는 데 걸렸습니다)

WITH words AS 
( SELECT REGEXP_SUBSTR('&txt', '\S+', 1, LEVEL) AS word 
     , LEVEL          AS num 
    FROM DUAL 
    CONNECT BY LEVEL <= LENGTH(REGEXP_REPLACE('&txt', '\S+\s*', 'X')) 
) 
SELECT SYS_CONNECT_BY_PATH(W.word, ' ') 
FROM words W 
CONNECT BY NOCYCLE PRIOR W.num != W.num 

편집 2 : 여분의 maxnum 물건을 제거했습니다. 이전 시도에서 남겨 두었습니다

+0

좋은 솔루션, 그냥 내가 뭘 필요해! – Metl

+0

정말 좋은 아이디어입니다. – josephj1989