DISTINCT для LISTAGG
24.01.2018
Иногда возникает задача объединения строковых аргументов в одну строку путем групповой функции LISTAGG. Может так оказаться, что строковые аргументы не уникальны, а на выходе нужна строка только с уникальными значениями. К аргументам обычных групповых функций можно применить функцию DISTINCT, но только не к функции LISTAGG. Групповая функция LISTAGG не допускает применение внутри ее аргументов функцию DISTINCT. Это можно легко обойти если функцию DISTINCT применить в подзапросе поверх которого будет применяться групповая функция  LISTAGG. Но изредка применить подзапрос без потери производительности затруднительно. И тут на помощь приходят регулярные выражения:
 
SELECT RTRIM(REGEXP_REPLACE(LISTAGG(val, ',') WITHIN GROUP (ORDER BY val) || ',', '([^,]+)(,\1)*(,|$)', '\1\3'), ',')
  FROM (
        SELECT 'AAA001' val FROM dual UNION ALL
        SELECT 'AAA001' FROM dual UNION ALL
        SELECT 'AAA002' FROM dual UNION ALL
        SELECT 'BBB001' FROM dual UNION ALL
        SELECT 'BBB001' FROM dual)
 
release 1.0