sql >> データベース >  >> RDS >> Oracle

OracleLISTAGG関数の使用方法

    OracleLISTAGG関数 は、order_by_clauseに基づいて、各GROUPのmeasure_columnの文字列を連結できるようにする分析関数です。これは、11gR2からOracleに存在します

    OracleのLISTAGG関数の構文は次のとおりです

    LISTAGG (measure_column [, 'delimiter'])
    WITHIN GROUP (order_by_clause) [OVER (query_partition_clause)]

    用語の説明

    measure_column 結果セットで値を連結する列または式。 measure_columnのnull値は無視されます。
    区切り文字 オプション。 measure_columnを区切るときに使用する区切り文字です。 結果を出力するときの値。
    order_by_clause 連結された値が返される順序を決定します

    LISTAGG関数のいくつかのケースと例を見てみましょう

    1)単一セットの集計関数として、LISTAGGはすべての行を操作し、単一の出力行を返します。

    SELECT LISTAGG(first_name, '; ')
    WITHIN GROUP (ORDER BY hire_date, last_name) "Employee_list",
    MIN(hire_date) "Earliest"
    FROM emp
    WHERE dept_no = 30;

    Employee_list                                                Earliest
    ------------------------------------------------------------ ---------
    TOM; BOB; BILL                                            17-JUN-18

    2)グループセットアグリゲートとして、関数はGROUP BY句で定義された各グループを操作し、出力行を返します。

    COLUMN employees FORMAT A50
    SELECT deptno, LISTAGG(ename, ';') WITHIN GROUP (ORDER BY ename) AS employees
    FROM emp
    GROUP BY deptno;
    DEPTNO EMPLOYEES
    ---------- --------------------------------------------------
    10 JOSHUA,KING,MILLER
    20 AJAY,FANES,SCOTT,SMITH
    30 TOM; BOB; BILL

    More Example

    select table_name,
    listagg(index_name, ',') within group (order by index_name) all_inds
    from user_indexes
    group by table_name;

    3)分析関数として、LISTAGGは、query_partition_clause内の1つ以上の式に基づいて、クエリ結果セットをグループに分割します。

    SQL> SELECT deptno
    , ename
    , hiredate
    , LISTAGG(ename, ',')
    WITHIN GROUP (ORDER BY hiredate)
    OVER (PARTITION BY deptno) AS employees
    FROM emp  order by deptno;

    DEPTNO ENAME HIREDATE EMPLOYEES
    ---------- ---------- ----------- -------------------------------------
    10 JOSHUA 09/06/2018 JOSHUA,KING,MILLER
    10 KING 17/11/2018 JOSHUA,KING,MILLER
    10 MILLER 23/01/2018 JOSHUA,KING,MILLER
    20 AJAY 17/12/2018 AJAY,FANES,SCOTT,SMITH
    20 FANES 02/04/2018 AJAY,FANES,SCOTT,SMITH
    20 SCOTT 19/04/2018 AJAY,FANES,SCOTT,SMITH
    20 SMITH 23/05/2018 AJAY,FANES,SCOTT,SMITH
    30 TOM 20/02/2018 TOM; BOB; BILL
    30 BOB 22/02/2018 TOM; BOB; BILL
    30 BILL 01/05/2018 TOM; BOB; BILL

    Oracleデータベース12cR2からのLISTAGG関数の追加

    返される最大文字数は4000バイトで、それを超えるとエラーが発生します

    ORA-01489:文字列連結の結果が長すぎます

    Oracle 12cR2では、オラクルはオーバーフローエラーを適切に処理するためのオーバーフロー切り捨てに関する句を提供しています。

    listagg (
    measure, ','
    [ on overflow (truncate|error) ]
    [ text ] [ (with|without) count ]
    ) within group (order by cols)

    これで、エラーセマンティクスと切り捨てセマンティクスのどちらが必要かを明示的に指定できます。 12cR2より前のコードは、デフォルトの動作であるため正常に機能します

    ここで、4kバイトを超えたときにエラーを返したくない場合は、オーバーフローの切り捨てを行います。 が解決策です。

    select table_name,
    listagg(index_name, ',' on overflow truncate) within group (order by index_name) inds
    from user_indexes
    group by table_name;

    切り捨てが発生した場合、Oracleは次の完全な値に切り捨てて戻します。その時点で、リストが切り捨てられたことをユーザーに通知する方法を制御できます。デフォルトでは、切り捨てが発生したことを示すインジケーターとして、文字列に3つのドット「…」を追加します。必要に応じて「…。」を変更できます

    「…」を「more」、「extra」、または「click for more」ハイパーリンクに置き換えたい場合は、新しい文字列を入力してください。

    select table_name,
    listagg(index_name, ',' on overflow truncate
    '|||'
    ) within group (order by index_name) inds
    from user_indexes
    group by table_name;

    デフォルトでは、truncateは欠落している値の数を表示します。数を表示したくない場合は、数えずに使用します

    select table_name,
    listagg(index_name, ',' on overflow truncate '....' without count) within group (order by index_name) inds
    from user_indexes
    group by table_name;

    11GR2以前のソリューション(10g、9i、11gR1)

    11gリリース2以降を実行していないが、WM_CONCAT関数が存在するバージョンのデータベースを実行している場合は、集計を実行するため、これはゼロエフォートソリューションです。これは実際には以下で説明するユーザー定義の集計関数の例ですが、Oracleがすべての作業を行ってくれます。

    COLUMN employees FORMAT A50
    SELECT deptno, wm_concat(ename) AS employees
    FROM emp
    GROUP BY deptno;
    EPTNO EMPLOYEES
    ---------- --------------------------------------------------
    10 JOSHUA,KING,MILLER
    20 AJAY,FANES,SCOTT,SMITH
    30 TOM; BOB; BILL

    これは、ユーザー定義関数を使用して実現することもできます。以下のasktomリンクを確認することをお勧めします。これは必読です

    Listaggの代替オプション

    OracleLISTAGG関数に関するこの投稿の内容を気に入っていただければ幸いです。

    関連記事
    列の自動インクリメント–Oracleおよびmysqlのデフォルト値としてのシーケンス
    Oracleの結合
    SQL集合演算子
    OracleplsqlでのgoogletranslateURLの使用方法
    の単一行関数sql
    oracleのdate関数

    1. Oracle正規表現。危険な範囲

    2. テーブルの中央に新しい列を挿入しますか?

    3. PostgreSQLの範囲内の日付リストを取得する

    4. rewriteBatchedStatements=trueを使用したMySQLおよびJDBC