Fortunatamente, funziona con listagg( ... ) funzione fornita da 11.2 (stiamo già correndo), quindi non abbiamo dovuto indagare ulteriormente:
listagg( abc, ',' ) within group ( order by abc )
(Dove wm_concat(...) è, come si dovrebbe sapere, una funzione interna e ufficialmente non supportata.)
una soluzione piuttosto interessante
(perché non è così gonfio) implementare il distinct la funzionalità avviene tramite la funzionalità regexp autoreferenziale che dovrebbe funzionare in molti casi:
regexp_replace(
listagg( abc, ',' ) within group ( order by abc )
, '(^|,)(.+)(,\2)+', '\1\2' )
(Forse/speriamo di vedere alcuni listagg( distinct abc ) funzionanti funzionalità in futuro, che sarebbe molto carina e interessante come wm_concat sintassi. Per esempio. questo non è un problema da molto tempo con string_agg( distinct abc ) di Postgres )
-- 1: postgres sql example:
select string_agg( distinct x, ',' ) from unnest('{a,b,a}'::text[]) as x`
Se l'elenco supera i 4000 caratteri , uno non può utilizzare listagg più (ORA-22922 di nuovo). Ma fortunatamente possiamo usare xmlagg funzione qui (come menzionato qui
).Se vuoi realizzare un distinct su un risultato troncato di 4000 caratteri qui, potresti commentare il (1) -linee segnate .
-- 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