幸いなことに、listagg( ... )
で動作します 11.2
から提供された機能 (すでに実行中です)、それ以上調査する必要はありませんでした:
listagg( abc, ',' ) within group ( order by abc )
(ここで wm_concat(...)
ご存知のように、内部の公式にサポートされていない関数です。)
かなり良い解決策
(それほど肥大化していないため) distinct
を実装するには 機能は、自己参照正規表現機能によるものです これは多くの場合に機能します:
regexp_replace(
listagg( abc, ',' ) within group ( order by abc )
, '(^|,)(.+)(,\2)+', '\1\2' )
(たぶん/願わくば、機能する listagg( distinct abc )
が表示されることを願っています これは wm_concat
のように非常にきちんとしたクールなものになるでしょう。 構文。例えば。 Postgres の string_agg( distinct abc )
で長い間使用されてきたので、これは問題ありません。 )
-- 1: postgres sql example:
select string_agg( distinct x, ',' ) from unnest('{a,b,a}'::text[]) as x`
リストが 4000 文字を超える場合 、listagg
は使用できません もう (ORA-22922
繰り返しますが、幸いなことに、xmlagg
を使用できます。 関数はこちら (前述のように こちら
) ).distinct
を実現したい場合 4000 文字の切り捨てられた結果 ここで、(1)
をアウトコメントすることができます -マークされた行 .
-- in smallercase everything that could/should be special for your query
-- comment in (1) to realize a distinct on a 4000 chars truncated result
WITH cfg AS (
SELECT
',' AS list_delim,
'([^,]+)(,\1)*(,|$)' AS list_dist_match, -- regexp match for distinct functionality
'\1\3' AS LIST_DIST_REPL -- regexp replace for distinct functionality
FROM DUAL
)
SELECT
--REGEXP_REPLACE( DBMS_LOB.SUBSTR( -- (1)
RTRIM( XMLAGG( XMLELEMENT( E, mycol, listdelim ).EXTRACT('//text()')
ORDER BY mycol ).GetClobVal(), LIST_DELIM )
--, 4000 ), LIST_DIST_MATCH, LIST_DIST_REPL ) -- (1)
AS mylist
FROM mytab, CFG