WM_CONCAT удаление дубликатов

У меня есть таблица, как показано ниже.

   colA       colB
   12345      NHS,CDE,BCD
   12345      NHS,ABC,DEF

Необходимо отобразить данные в формате ниже

   colA       colB
   12345      NHS,ABC,BCD,CDE,DEF

Мне нужно обобщенное решение, чтобы удалить дубликат NHS, который идет первым, а затем поместить оставшиеся слова в алфавитном порядке.

2 ответа

Решение

Во-первых, никогда не используйте WM_CONCAT, так как он недокументирован и больше не доступен в последней версии 12c. См. Почему бы не использовать функцию WM_CONCAT в Oracle? и почему wm_concat не работает здесь?

Так как вы на 11g, вы можете использовать LISTAGG.

Приведенный ниже запрос выполняет следующие действия:

  1. Разбить строку через запятую на строки.
  2. Примените агрегирование строк, используя LISTAGG.
  3. ВыражениеCASE для обработки пользовательского заказа.

Например,

SQL> WITH DATA AS(
  2      SELECT 12345 colA, 'NHS,CDE,BCD' colB FROM dual UNION ALL
  3      SELECT 12345 colA, 'NHS,ABC,DEF' colB FROM dual
  4      )
  5  SELECT cola,
  6    listagg(colb, ',') WITHIN GROUP(
  7  ORDER BY
  8    CASE colb
  9      WHEN 'NHS'
 10      THEN 1
 11      ELSE 2
 12    END, colb) colb
 13  FROM
 14    (SELECT DISTINCT cola,
 15      trim(regexp_substr(colb, '[^,]+', 1, LEVEL)) colb
 16    FROM DATA
 17      CONNECT BY LEVEL <= regexp_count(colb, ',')+1
 18    ORDER BY colb
 19    )
 20  GROUP BY cola
 21  /

      COLA COLB
---------- ------------------------------
     12345 NHS,ABC,BCD,CDE,DEF

Редактировать Как указывало @AlexPoole, явное упорядочение отсутствовало, и предыдущий запрос (см. Историю редактирования) основывался на различном упорядочении значений.

WITH t AS
  (SELECT col1,wm_concat(col2) AS col2 FROM test1 GROUP BY col1
  ) , t1 AS
  ( SELECT DISTINCT col1, regexp_substr(col2, '[^,]+', 1, rownum) names
  FROM t
    CONNECT BY rownum <= LENGTH(regexp_replace(col2, '[^,]'))+1
  ORDER BY names
  )
SELECT col1,wm_concat(names) AS names FROM t1 GROUP BY col1
Другие вопросы по тегам