ここでは完全に一般的にこれを行うための一つの方法だ、私は問題を正しく理解した場合は、カンマで区切られた文字列を与えられました。後で文字列の中で繰り返される各シンボル(トークン)をNULL
に置き換えますが、すべてのコンマをプレースホルダとして保持します。解決方法は、元の文字列に既にNULL
のプレースホルダがある場合(つまり、トークンがない連続したコンマ極端な場合、元の文字列は空でもかまいません(OracleではNULL
と同じです)。
問題の唯一の他の妥当な意味は、「シンボル」または「トークン」は、直ちに同じシンボルが続く場合にのみ削除することです。つまり、a,a,a,b,b,a,a,b,b,b
のような入力は,,a,,b,,a,,,b
になるはずです。最初の解釈では、それは,,,,,,a,,,b
になるはずです。以下の解決策は、「最初の解釈」(a
と修正された文字列に残っているのはb
の1つだけです)を実装しています。 OPの質問は、どの解釈が望まれるかについては明確ではない。「第2の解釈」が望ましい場合は、以下の解決策を変更することができます(基本的な「Tabibitosanメソッド」を使用して同じ連続値を識別します)。
トークンはNULL
のトークンが存在する可能性があるため注意深く分割し、各個別シンボルの最後のオカレンスを特定し、すべてのヌルトークンと「グループの最後」でないすべてのトークンをプレースホルダシンボルここでは「〜」を使用しました。入力文字列で使用されていない記号である必要があります)、すべてをLISTAGG()
で集計し、すべてのプレースホルダ記号(~
)を削除します。 LISTAGG()
は入力からNULL
を削除するため、プレースホルダが必要です(Oracle開発者が残念な選択です)。
解決方法は正規表現を使用します。コードをもっと複雑にするという代償を払って、パフォーマンスが非常に重要な場合は避けることができます(代わりにINSTR
とSUBSTR
を使用してください)。
with
-- begin test data definition (do not include in final query)
test_data as (
select 1 as id, 'a,a,a,b,b,c' as str from dual union all
select 2 , '' from dual union all
select 3 , 'a,b,a,b,b,a' from dual union all
select 4 , 'x,y,z,z,z' from dual union all
select 5 , 'a,a,a,a' from dual union all
select 6 , 'a,b,c,c,a' from dual union all
select 7 , 'x' from dual union all
select 8 , 'p,q,r' from dual union all
select 9 , 'a,b,,,a,c' from dual
),
-- end of test data; solution (query) continues below this line
prep as (
select id, str, level as lvl,
regexp_substr(str, '([^,]*)(,|$)', 1, level, null, 1) as token
from test_data
connect by level <= regexp_count(str, ',') + 1
and prior id = id
and prior sys_guid() is not null
),
with_rn as (
select id, str, lvl, token,
row_number() over (partition by id, token order by lvl desc) as rn
from prep
)
select id, str,
translate(listagg (case when token is null or rn > 1 then '~'
else token end, ','
) within group (order by lvl), 'x~', 'x'
) as modif_str
from with_rn
group by id, str
;
出力:
ID STR MODIF_STR
--- -------------- --------------
1 a,a,a,b,b,c ,,a,,b,c
2
3 a,b,a,b,b,a ,,,,b,a
4 x,y,z,z,z x,y,,,z
5 a,a,a,a ,,,a
6 a,b,c,c,a ,b,,c,a
7 x x
8 p,q,r p,q,r
9 a,b,,,a,c ,b,,,a,c
9 rows selected.
あなたは明確交換のルールを記述してくださいすることができます。私はなぜ2番目の例が 'a、b、a'に置き換えられるのか理解できません。 – Kacper
@Kacper私が理解しているように、 'a、b、a 'は2つの最初の' A'と最初の 'B'値を置き換えます。 'a、b'は' A'の最初の値と 'B'の最初の値を置き換えます。 – sagi
私はルールを理解していません。テキストは最初の複数の出現を置き換えますので、私はそれぞれの文字の出現を別々に扱うと、Ex1の結果が 'a、b、b、c'または' a、b、c 'であることを意味します。 – Kacper