Oracle
 sql >> база данни >  >> RDS >> Oracle

Агрегиране на различни стойности в колекции в SQL GROUP BY

Адаптирано от моя отговор към друг въпрос.

Настройка на 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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да инсталирам Oracle Instant Client на Mac?

  2. Параметризирана заявка в проблем с Oracle

  3. Заявка в Oracle за избор с подзаявка

  4. Oracle Rolling или Running totals по месеци

  5. Как да симулирам 32-битово препълване на цели числа със знак в PL/SQL?