8

通常、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.

','セパレーター( )を関数のような他の文字に'.'変更することは可能ですか?'|'WM_CONCAT()

または、次のように実行できるユーザー定義関数を作成しますWM_CONCAT()か?

4

4 に答える 4

16

を使用することもできます 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. |

SQLフィドル

UPDATEリスト内の個別のテキスト値を取得する必要がある場合

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

SQLフィドル

于 2013-05-28T08:11:18.350 に答える
4

セパレーター (',') を '.' のような他の文字に変更することは可能ですか? または '|' WM_CONCAT() 関数の?

WM_CONCATこれは文書化されていない機能であり、最新の12c バージョンから削除されているため、使用しないでください。機能に依存していたアプリケーションは、 にアップグレードすると機能しなくなります。Oracle で WM_CONCAT 関数を使用しない理由を参照してください。wm_concat12c

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.

「<strong>無効な識別子」エラーが表示されます。

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

したがって、最新バージョンでは利用できなくなった文書化されていない機能に依存しても意味がありません。

さまざまな文字列集約手法があります。

  • 11gR2 以降のLISTAGG

例えば、

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.
  • 9i 以降の ROW_NUMBER ()およびSYS_CONNECT_BY_PATH関数

例えば、

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.
  • AskTomで説明されているユーザー定義の集計関数STRAGG
  • 10g以上のCOLLECT機能

ここにティム・ホールによるいくつかの良い例があります。

于 2015-05-16T07:20:52.463 に答える
4

varchar2 を返し、4000 バイトに制限されている LISTAGG の問題

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

回避策を1つ見つけましたが、見た目が悪く、速度が大幅に低下します

SELECT EXTRACT(XMLTYPE('<doc>' || XMLAGG(XMLTYPE('<ln>' || LEVEL || CHR(10) || '</ln>')).GetClobVal() || '</doc>'), '/doc/ln/text()').GetClobVal()
  FROM Dual
CONNECT BY LEVEL < 2000
于 2014-07-03T12:51:44.497 に答える
1

以下は、ORACLE 10.2.0.5.0 データベースで機能しました。

SELECT col_id, replace(wm_concat(col_text), ',', ' ') AS sentence
  FROM foo
 GROUP BY col_id;
于 2015-06-23T22:42:05.893 に答える