【问题标题】:Mutliple rows into a single row with comma-separated in Oracle在 Oracle 中,多行以逗号分隔为单行
【发布时间】:2021-10-12 07:48:32
【问题描述】:

我有一个关于 Oracle 的问题:我想将多行组合成一个以逗号分隔的单行。

create table emp ( empid varchar2 (100));

insert into emp values ('90322');
insert into emp values ('89333');
insert into emp values ('458999');

基于以上数据,我希望输出如下:

'90322', '89333', '458999'

我尝试使用此代码:

select listagg(empid ,', ') within group(order by empid ) csv
from emp;

select rtrim(xmlagg(xmlelement(e,empid,', ').extract('//text()') order by empid).getclobval(),', ') x
from emp;

它只适用于几行。如果emp 表有超过 5000 行,那么它不再工作,我得到一个错误:

错误执行 1:1 ORA-01489: 字符串连接的结果太长

请告诉我如何编写查询以在 Oracle 中完成此任务。

【问题讨论】:

  • 第二条语句应该可以工作(在数据库版本 12.218 上尝试了 50k ID 成功,而版本 11 发生超时在同一个小提琴上,但没有错误)

标签: sql oracle oracle11g group-concat


【解决方案1】:

您可以创建用户定义的聚合函数:

CREATE OR REPLACE TYPE CLOBAggregation AS OBJECT(
  value CLOB,

  STATIC FUNCTION ODCIAggregateInitialize(
    ctx         IN OUT CLOBAggregation
  ) RETURN NUMBER,

  MEMBER FUNCTION ODCIAggregateIterate(
    self        IN OUT CLOBAggregation,
    value       IN     CLOB
  ) RETURN NUMBER,

  MEMBER FUNCTION ODCIAggregateTerminate(
    self        IN OUT CLOBAggregation,
    returnValue    OUT CLOB,
    flags       IN     NUMBER
  ) RETURN NUMBER,

  MEMBER FUNCTION ODCIAggregateMerge(
    self        IN OUT CLOBAggregation,
    ctx         IN OUT CLOBAggregation
  ) RETURN NUMBER
);
/

CREATE OR REPLACE TYPE BODY CLOBAggregation
IS
  STATIC FUNCTION ODCIAggregateInitialize(
    ctx         IN OUT CLOBAggregation
  ) RETURN NUMBER
  IS
  BEGIN
    ctx := CLOBAggregation( NULL );
    RETURN ODCIConst.SUCCESS;
  END;

  MEMBER FUNCTION ODCIAggregateIterate(
    self        IN OUT CLOBAggregation,
    value       IN     CLOB
  ) RETURN NUMBER
  IS
  BEGIN
    IF value IS NULL THEN
      NULL;
    ELSIF self.value IS NULL THEN
      self.value := value;
    ELSE
      self.value := self.value || ',' || value;
    END IF;
    RETURN ODCIConst.SUCCESS;
  END;

  MEMBER FUNCTION ODCIAggregateTerminate(
    self        IN OUT CLOBAggregation,
    returnValue    OUT CLOB,
    flags       IN     NUMBER
  ) RETURN NUMBER
  IS
  BEGIN
    returnValue := self.value;
    RETURN ODCIConst.SUCCESS;
  END;

  MEMBER FUNCTION ODCIAggregateMerge(
    self        IN OUT CLOBAggregation,
    ctx         IN OUT CLOBAggregation
  ) RETURN NUMBER
  IS
  BEGIN
    IF self.value IS NULL THEN
      self.value := ctx.value;
    ELSIF ctx.value IS NULL THEN
      NULL;
    ELSE
      self.value := self.value || ',' || ctx.value;
    END IF;
    RETURN ODCIConst.SUCCESS;
  END;
END;
/

CREATE FUNCTION CLOB_AGG( value CLOB )
RETURN CLOB
PARALLEL_ENABLE AGGREGATE USING CLOBAggregation;
/

然后:

SELECT CLOB_AGG(empid) csv
FROM   (
  SELECT empid
  FROM   emp
  ORDER BY empid
);

db小提琴here

【讨论】:

    猜你喜欢
    • 2013-09-17
    • 1970-01-01
    • 2019-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多