私がよく分かっているのであれば、 '、'をスペースで置き換えるだけでなく、よりスマートな方法で重複を削除する必要があります。
私が代わりにスペースで動作するように、その式を変更する場合「」、私はあなたが必要なもの、'A B A C D'
を与える
select regexp_replace('A B A A C D' ,'([^ ]+)([ ]*\1)+', '\1') from dual
をしませ得ます。
あなたに必要な結果が複雑もう少し、以下のことができ取得する方法は:ここ
with string(s) as (select 'A B A A C D' from dual)
select listagg(case when rn = 1 then str end, ' ') within group (order by lev)
from (
select str, row_number() over (partition by str order by 1) rn, lev
from (
SELECT trim(regexp_substr(s, '[^ ]+', 1, level)) str,
level as lev
FROM string
CONNECT BY instr(s, ' ', 1, level - 1) > 0
)
)
私の主な問題は、私は非隣接の重複をチェックする正規表現を構築することはできませんよということです、だから、私は文字列を分割し、重複をチェックし、重複していない値を再び集計して、順序を保つ必要があります。
あなたは結果の文字列内のトークンの順番を気にしない場合は、これを簡略化することができる。
with string(s) as (select 'A B A A C D' from dual)
select listagg(str, ' ') within group (order by 1)
from (
SELECT distinct trim(regexp_substr(s, '[^ ]+', 1, level)) as str
FROM string
CONNECT BY instr(s, ' ', 1, level - 1) > 0
)
長く待つ必要はありませんでした。 :-)しかし、唯一の改善は外側のクエリです - rn = 1の行だけを使用してください。これは、この場合に可能な唯一の単純化です。 – mathguy
@mathguy - 私はあまりにも多くのネスティングを持っていた感覚を持っていた::)まだいくつかの正規表現の組み合わせが分割を避けることができますが、あまりにも多くの希望... – Aleksej
長い選択ネストはヒットします。それでも私は正しい解決策を超えて処理時間を犠牲にすることができます。ありがとう –