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

SQLGROUPBYのコレクション内の個別の値を集計します

    私の答え から引用 別の質問に。

    Oracleセットアップ

    CREATE OR REPLACE TYPE VARCHAR2s_Table IS TABLE OF VARCHAR2(100);
    /
    

    ユーザー定義の集計タイプを作成します:

    CREATE OR REPLACE TYPE Varchar2sTableUnion AS OBJECT(
      list VARCHAR2s_Table,
    
      STATIC FUNCTION ODCIAggregateInitialize(
        ctx         IN OUT Varchar2sTableUnion
      ) RETURN NUMBER,
    
      MEMBER FUNCTION ODCIAggregateIterate(
        self        IN OUT Varchar2sTableUnion,
        value       IN     VARCHAR2s_Table
      ) RETURN NUMBER,
    
      MEMBER FUNCTION ODCIAggregateTerminate(
        self        IN OUT Varchar2sTableUnion,
        returnValue    OUT VARCHAR2s_Table,
        flags       IN     NUMBER
      ) RETURN NUMBER,
    
      MEMBER FUNCTION ODCIAggregateMerge(
        self        IN OUT Varchar2sTableUnion,
        ctx         IN OUT Varchar2sTableUnion
      ) RETURN NUMBER
    );
    /
    
    CREATE OR REPLACE TYPE BODY Varchar2sTableUnion
    IS
      STATIC FUNCTION ODCIAggregateInitialize(
        ctx         IN OUT Varchar2sTableUnion
      ) RETURN NUMBER
      IS
      BEGIN
        ctx := Varchar2sTableUnion( NULL );
        RETURN ODCIConst.SUCCESS;
      END;
    
      MEMBER FUNCTION ODCIAggregateIterate(
        self        IN OUT Varchar2sTableUnion,
        value       IN     VARCHAR2s_Table
      ) RETURN NUMBER
      IS
      BEGIN
        IF value IS NULL THEN
          NULL;
        ELSIF self.list IS NULL THEN
          self.list := value;
        ELSE
          self.list := self.list MULTISET UNION DISTINCT value;
        END IF;
        RETURN ODCIConst.SUCCESS;
      END;
    
      MEMBER FUNCTION ODCIAggregateTerminate(
        self        IN OUT Varchar2sTableUnion,
        returnValue    OUT VARCHAR2s_Table,
        flags       IN     NUMBER
      ) RETURN NUMBER
      IS
      BEGIN
        returnValue := self.list;
        RETURN ODCIConst.SUCCESS;
      END;
    
      MEMBER FUNCTION ODCIAggregateMerge(
        self        IN OUT Varchar2sTableUnion,
        ctx         IN OUT Varchar2sTableUnion
      ) RETURN NUMBER
      IS
      BEGIN
        IF self.list IS NULL THEN
          self.list := ctx.list;
        ELSIF ctx.list IS NULL THEN
          NULL;
        ELSE
          self.list := self.list MULTISET UNION DISTINCT ctx.list;
        END IF;
        RETURN ODCIConst.SUCCESS;
      END;
    END;
    /
    

    ユーザー定義の集計関数を作成します:

    CREATE FUNCTION MULTISET_UNION( list VARCHAR2s_Table )
    RETURN VARCHAR2s_Table
    PARALLEL_ENABLE AGGREGATE USING Varchar2sTableUnion;
    /
    

    クエリ

    次に、それを使用してクエリで集計を実行できます:

    WITH test_data (id, a_list) AS
           (SELECT 1,
                   varchar2s_table ('A', 'B', 'C')
            FROM   DUAL
            UNION ALL
            SELECT 1,
                   varchar2s_table ('C', 'D', 'E')
            FROM   DUAL)
    SELECT id,
           MULTISET_UNION( a_list )
    FROM   test_data
    GROUP BY id
    

    出力

    ID MULTISET_UNION(A_LIST)
    -- -------------------------------------------
     1 SCHEMA.VARCHAR2S_TABLE('A','B','C','D','E')
    



    1. PHP/MYSQL複数のテーブルを結合する

    2. Oracle:条件付きの全文検索

    3. MySQLのUNIX_TIMESTAMPとNOW()の違い

    4. DockerからExited(1)を使用したmysql