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