Felizmente, funciona com o
listagg( ... )
função fornecida desde 11.2
(já estamos rodando), então não tivemos que investigar mais:listagg( abc, ',' ) within group ( order by abc )
(Onde
wm_concat(...)
é, como se deve saber, alguma função interna e oficialmente não suportada.) uma solução bastante interessante (porque não é tão inchado) implementar o
distinct
a funcionalidade é por meio da funcionalidade regexp de auto-referência que deve funcionar em muitos casos:regexp_replace(
listagg( abc, ',' ) within group ( order by abc )
, '(^|,)(.+)(,\2)+', '\1\2' )
(Talvez/Esperamos ver algum
listagg( distinct abc )
funcionando funcionalidade no futuro, o que seria muito legal e legal como o wm_concat
sintaxe. Por exemplo. isso não é problema desde muito tempo com o string_agg( distinct abc )
do Postgres ) -- 1: postgres sql example:
select string_agg( distinct x, ',' ) from unnest('{a,b,a}'::text[]) as x`
Se a lista exceder 4.000 caracteres , um não pode usar
listagg
mais (ORA-22922
novamente). Mas felizmente podemos usar o xmlagg
função aqui (como mencionado aqui
).Se você deseja realizar um distinct
em um resultado truncado de 4.000 caracteres aqui, você pode comentar o (1)
-linhas marcadas . -- 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