sql - 在 SQL GROUP BY 中聚合集合中的不同值

标签 sql oracle

我有一个表,其中包含集合类型。我想从表中SELECTGROUP BY 某些列。我希望每个组的结果都包含一个集合,该集合包含该组中所有单独集合的不同并集。

例如,

CREATE OR REPLACE TYPE my_varchar2_list AS TABLE OF VARCHAR2 (80);

WITH test_data (id, a_list) AS
       (SELECT 1,
               NEW my_varchar2_list ('A', 'B', 'C')
        FROM   DUAL
        UNION ALL
        SELECT 1,
               NEW my_varchar2_list ('C', 'D', 'E')
        FROM   DUAL)
SELECT id,
       ... some magic syntax here...
FROM   test_data
GROUP BY id

Desired results:

1,  ('A','B','C','D','E')

我在寻找答案

我只是在寻找可以插入上面的“魔法语法在这里”占位符的表达式。我知道我可以通过将 TABLE(a_list) 连接到主表或以其他方式重组我的查询(或者,当然,使用 PL/SQL)来完成聚合。但是,我现在想避免使用此类解决方案。

最佳答案

改编自my answer另一个问题。

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')

关于sql - 在 SQL GROUP BY 中聚合集合中的不同值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43643078/

相关文章:

mysql - 如何在MySQL中进行条件插入?

php - 使用 mysqli 查询失败

php - 如何更新我的查询以符合启用的 sql_mode=only_full_group_by?

mysql - 如何基于多列键进行子选择

oracle - 在 apex 中创建一个包含两个详细信息的主详细信息页面

sql - 为什么表上的 CONNECT BY LEVEL 返回额外的行?

sql - 使用 Oracle SQL 获取表中所有列的值计数

mysql - 使用专有的 ODBC 驱动程序将 MySQL 连接到外部数据源

oracle - Oracle中如何计算校验和?

sql - 当必须根据条件对记录进行分组时如何选择最多 x 行