За щастие работи с 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
синтаксис. напр. това не е проблем от дълго време на string_agg( distinct abc )
на Postgres )
-- 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