2011-08-02 30 views
6

Tôi nghĩ rằng tôi có một yêu cầu phức tạp.Oracle - hoán vị tổ hợp chuỗi

Đó là một hoán vị tổ hợp sử dụng Oracle 10.2, tôi có thể giải quyết nó bằng cách sử dụng tham gia cartes, nhưng tôi nghĩ rằng nó cần một số cải tiến để làm cho nó đơn giản và linh hoạt hơn.

Hành vi chính.

chuỗi đầu vào: 'one two'

đầu ra: 'one' 'hai' 'one two' 'hai một'

Đối với giải pháp của tôi, tôi đã hạn chế số chuỗi đến 5 (lưu ý rằng đầu ra là một số gần giai thừa)

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

Có phải trong SQL hay bạn cũng có thể sử dụng plsql? – Rene

+1

Bạn sẽ có số lượng chuỗi cố định không? Bởi vì nếu nó có thể khác nhau, thì tôi không thấy làm thế nào bạn có thể tránh đi làm tuyến đường PL/SQL. Việc bạn sử dụng từ "linh hoạt" cho thấy đó là những gì bạn đang nghĩ. – APC

+0

có, nó có thể được thực hiện bằng cách sử dụng plsql. – Metl

Trả lời

8

Chỉnh sửa: Có phiên bản chung. Thực sự đơn giản cuối cùng (nhưng đã cho tôi một thời gian để đạt được điều đó)

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: Removed thứ maxnum dư thừa. Trái qua các lần thử trước đây

+0

giải pháp tuyệt vời, chỉ là những gì tôi cần! – Metl

+0

ý tưởng thực sự hay – josephj1989

Các vấn đề liên quan