Изменение разделителя функции WM CONCAT Oracle 11gR2
обычно WM_CONCAT-это агрегатная функция, которая возвращает значения из таблицы, разделенные запятой, как здесь.
Предположим у меня есть таблица foo
такой:
col_id | col_text
111 | This
111 | is
111 | a
111 | test.
если я использую этот запрос:
SELECT CAST(WM_CONCAT(col_text) AS VARCHAR2(100)), col_id FROM foo
результат будет
This, is, a, test.
можно ли изменить разделитель(','
) для других персонажей, таких как '.'
или '|'
на
4 ответов
вы можете использовать LISTAGG
.
SELECT col_id,
LISTAGG(col_text, '|') WITHIN GROUP (ORDER BY col_text) text
FROM table1
GROUP BY col_id
выход:
| COL_ID | TEXT |
----------------------------
| 111 | This|a|is|test. |
обновление Если вам нужно получить отдельные текстовые значения в списке
SELECT col_id,
LISTAGG(col_text, '|')
WITHIN GROUP (ORDER BY col_text) text
FROM
(
SELECT DISTINCT col_id, col_text
FROM table1
)
GROUP BY col_id
проблема с LISTAGG, что он возвращает varchar2 и ограничен 4000 байтами
SELECT LISTAGG(LEVEL, CHR(10)) WITHIN GROUP (ORDER BY NULL)
FROM Dual
CONNECT BY LEVEL < 2000
ORA-01489 Result of string concat is too large
Я нашел один обходной путь, но он выглядит уродливым и mutch медленнее
SELECT EXTRACT(XMLTYPE('<doc>' || XMLAGG(XMLTYPE('<ln>' || LEVEL || CHR(10) || '</ln>')).GetClobVal() || '</doc>'), '/doc/ln/text()').GetClobVal()
FROM Dual
CONNECT BY LEVEL < 2000
можно ли изменить разделитель(',') на другие символы, такие как '.'или' | ' функции WM_CONCAT ()?
не используйте WM_CONCAT
С недокументированные функции и удалены из последних 12C версии. Любое приложение, которое полагалось на wm_concat
функция не будет работать после обновления до 12c
. См.почему бы не использовать функцию WM_CONCAT в Оракул?
SQL> select banner from v$version where rownum = 1;
BANNER
----------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
SQL> SELECT object_name
2 FROM dba_objects
3 WHERE owner='WMSYS'
4 AND object_name LIKE 'WM\_%' ESCAPE '\';
OBJECT_NAME
----------------------------------------------------------------------------
WM_REPLICATION_INFO
WM_RDIFF
WM_PERIOD
WM_PERIOD
WM_OVERLAPS
WM_MEETS
WM_LESSTHAN
WM_LDIFF
WM_INTERSECTION
WM_INSTALLATION
WM_GREATERTHAN
WM_EVENTS_INFO
WM_ERROR
WM_ERROR
WM_EQUALS
WM_DDL_UTIL
WM_DDL_UTIL
WM_CONTAINS
WM_COMPRESS_BATCH_SIZES
WM_COMPRESSIBLE_TABLES
20 rows selected.
вы получите "неверный идентификатор" ошибка:
SQL> SELECT banner FROM v$version;
BANNER
----------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
PL/SQL Release 12.1.0.1.0 - Production
CORE 12.1.0.1.0 Production
TNS for 64-bit Windows: Version 12.1.0.1.0 - Production
NLSRTL Version 12.1.0.1.0 - Production
SQL> SELECT deptno, wm_concat(ename) FROM emp;
SELECT deptno, wm_concat(ename) FROM emp
*
ERROR at line 1:
ORA-00904: "WM_CONCAT": invalid identifier
поэтому нет смысла полагаться на недокументированные функции который больше не доступен в последней версии.
различные методы агрегирования строк:
- LISTAGG в 11gR2 и до
для пример,
SELECT deptno, LISTAGG(ename, ',') WITHIN GROUP (ORDER BY ename) AS employees
FROM emp
GROUP BY deptno;
DEPTNO EMPLOYEES
---------- --------------------------------------------------
10 CLARK,KING,MILLER
20 ADAMS,FORD,JONES,SCOTT,SMITH
30 ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD
3 rows selected.
- функции row_number() и SYS_CONNECT_BY_PATH функции в 9i и до
например,
SELECT deptno,
LTRIM(MAX(SYS_CONNECT_BY_PATH(ename,','))
KEEP (DENSE_RANK LAST ORDER BY curr),',') AS employees
FROM (SELECT deptno,
ename,
ROW_NUMBER() OVER (PARTITION BY deptno ORDER BY ename) AS curr,
ROW_NUMBER() OVER (PARTITION BY deptno ORDER BY ename) -1 AS prev
FROM emp)
GROUP BY deptno
CONNECT BY prev = PRIOR curr AND deptno = PRIOR deptno
START WITH curr = 1;
DEPTNO EMPLOYEES
---------- --------------------------------------------------
10 CLARK,KING,MILLER
20 ADAMS,FORD,JONES,SCOTT,SMITH
30 ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD
3 rows selected.
- пользовательская агрегатная функция STRAGG описано в AskTom.
- собрать функция в 10g и вверх
несколько хороших примеров Тима Холла здесь.
следующее работало для меня в базе данных ORACLE 10.2.0.5.0:
SELECT col_id, replace(wm_concat(col_text), ',', ' ') AS sentence
FROM foo
GROUP BY col_id;