May mắn thay, nó hoạt động với listagg( ... )
chức năng được cung cấp kể từ 11.2
(chúng tôi đang chạy), vì vậy chúng tôi không phải điều tra thêm:
listagg( abc, ',' ) within group ( order by abc )
(Trong đó wm_concat(...)
, như người ta nên biết, một số chức năng nội bộ và không được hỗ trợ chính thức.)
một giải pháp khá hay
(vì nó không quá cồng kềnh) để triển khai distinct
chức năng thông qua chức năng regexp tự tham chiếu sẽ hoạt động trong nhiều trường hợp:
regexp_replace(
listagg( abc, ',' ) within group ( order by abc )
, '(^|,)(.+)(,\2)+', '\1\2' )
(Có thể / Hy vọng rằng chúng ta sẽ thấy một số listagg( distinct abc )
hoạt động trong tương lai, sẽ rất gọn gàng và tuyệt vời như wm_concat
cú pháp. Ví dụ. điều này không thành vấn đề vì đã lâu với string_agg( distinct abc )
của Postgres )
-- 1: postgres sql example:
select string_agg( distinct x, ',' ) from unnest('{a,b,a}'::text[]) as x`
Nếu danh sách vượt quá 4000 ký tự , một không thể sử dụng listagg
nữa (ORA-22922
một lần nữa). Nhưng thật may mắn là chúng ta có thể sử dụng xmlagg
chức năng tại đây (như đã đề cập tại đây
). Nếu bạn muốn nhận ra distinct
trên kết quả bị cắt ngắn 4000 ký tự ở đây, bạn có thể ủng hộ (1)
-đường đánh dấu .
-- 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