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.
Приведенный ниже запрос выполняет следующие действия:
- Разбить строку через запятую на строки.
- Примените агрегирование строк, используя LISTAGG.
- Выражение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