2011-08-02 41 views
6

我認爲我有一個複雜的需求。Oracle - 字符串組合排列

這是一個使用Oracle 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 

Edit2:刪除多餘的maxnum東西。從以前的嘗試中遺留下來

+0

偉大的解決方案,正是我需要的! – Metl

+0

真是個好主意 – josephj1989