在Oracle 11.2之前,我使用自定义聚合函数将列连接成一行. 11.2添加了LISTAGG功能,所以我尝试使用它.我的问题是我需要消除结果中的重复项,似乎无法做到这一点.这是一个例子.
CREATE TABLE ListAggTest AS ( SELECT rownum Num1,DECODE(rownum,1,'2',to_char(rownum)) Num2 FROM dual CONNECT BY rownum<=6 ); SELECT * FROM ListAggTest; NUM1 NUM2 ---------- --------------------- 1 2 2 2 << Duplicate 2 3 3 4 4 5 5 6 6
我想看到的是:
NUM1 NUM2S ---------- -------------------- 1 2-3-4-5-6 2 2-3-4-5-6 3 2-3-4-5-6 4 2-3-4-5-6 5 2-3-4-5-6 6 2-3-4-5-6
这是一个closeag的listagg版本,但不会消除重复.
SELECT Num1,listagg(Num2,'-') WITHIN GROUP (ORDER BY NULL) OVER () Num2s FROM ListAggTest;
在使用listagg连接后,您可以使用正则表达式和
regexp_replace
删除重复项:
SELECT Num1,RTRIM( REGEXP_REPLACE( (listagg(Num2,'-') WITHIN GROUP (ORDER BY Num2) OVER ()),'([^-]*)(-\1)+($|-)','\1\3'),'-') Num2s FROM ListAggTest;
如果Oracle的正则表达式支持先行或非捕获组,这可能更整洁,but it doesn’t.
但是,此解决方案确实避免多次扫描源.
DBFiddle here