Untungnya, ini bekerja dengan listagg( ... )
fungsi yang disediakan sejak 11.2
(kami sudah berjalan), jadi kami tidak perlu menyelidiki lebih lanjut:
listagg( abc, ',' ) within group ( order by abc )
(Di mana wm_concat(...)
adalah, seperti yang harus diketahui, beberapa fungsi internal dan tidak didukung secara resmi.)
solusi yang cukup bagus
(karena tidak terlalu membengkak) untuk menerapkan distinct
fungsionalitasnya adalah melalui fungsi regexp referensi sendiri yang seharusnya berfungsi dalam banyak kasus:
regexp_replace(
listagg( abc, ',' ) within group ( order by abc )
, '(^|,)(.+)(,\2)+', '\1\2' )
(Mungkin/Semoga kita akan melihat beberapa listagg( distinct abc )
fungsionalitas di masa depan, yang akan sangat rapi dan keren seperti wm_concat
sintaksis. Misalnya. ini bukan masalah sejak lama dengan string_agg( distinct abc )
Postgres )
-- 1: postgres sql example:
select string_agg( distinct x, ',' ) from unnest('{a,b,a}'::text[]) as x`
Jika daftar melebihi 4000 karakter , seseorang tidak dapat menggunakan listagg
lagi (ORA-22922
lagi). Tapi untungnya kita bisa menggunakan xmlagg
fungsi di sini (seperti yang disebutkan di sini
).Jika Anda ingin mewujudkan distinct
pada hasil terpotong 4000 karakter di sini, Anda dapat mengkomentari (1)
-garis yang ditandai .
-- 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