在 ORACLE 中,有没有办法使用两个表将多行行连接成一个行,其中最终值用逗号分隔?

Posted

技术标签:

【中文标题】在 ORACLE 中,有没有办法使用两个表将多行行连接成一个行,其中最终值用逗号分隔?【英文标题】:Is there a way, in ORACLE, to join multiple row lines into a single one, using two tables, where the final values are separated by commas? 【发布时间】:2010-12-06 20:51:09 【问题描述】:

有没有办法使用 ORACLE 中的值用逗号分隔的两个表将多行连接到一个单独的行?

例子:

表1

IdN Name 
---------
1   A 
2   B 
3   C 

表 2

IdC Car
------------
1    Ferrari
1    BMW
2    SEAT
2    FIAT
3    FORD

结果为:

A    Ferrari,BMW
B    SEAT,FIAT
C    FORD

我想知道是否有这样的事情:

SELECT NAME,CAR
FROM TABLE1, TABLE2
where TABLE1.IdN=TABLE2.IdC

这会返回类似:

法拉利 宝马 B座 B 菲亚特 C福特

有没有一种简单的方法可以用逗号分隔值“连接”成一行?

【问题讨论】:

How do I Create a Comma-Separated List using a SQL Query?的可能重复 还有:***.com/questions/4157295/add-a-comma-in-oracle 【参考方案1】:

看看 LISTAGG

http://www.oracle-base.com/articles/misc/StringAggregationTechniques.php

类似:

SELECT NAME, LISTAGG(CAR, ',') WITHIN GROUP (ORDER BY CAR) AS CARS
FROM   (SELECT NAME,CAR
FROM TABLE1, TABLE2
where TABLE1.IdN=TABLE2.IdC)
GROUP BY NAME;

【讨论】:

谢谢!我使用 wm_concat 因为 LISTAGG 无法识别。 (认为​​我使用的是比 11g 第 2 版更旧的版本。SELECT NAME, wm_concat(CAR) as CARS FROM TABLE1, TABLE2 where TABLE1.IdN=TABLE2.IdC GROUP BY NAME;【参考方案2】:

查找用户定义的聚合函数。如果您确实需要将它们全部列出在一列中,您可以设置一个聚合函数,它会为您完成。

Declare 
   sql_txt      Varchar2(4000); 
   Rec_cnt      Number; 
Begin 
   Select Count(*) 
     Into Rec_Cnt 
     From User_Types 
    Where Type_Name = 'VCARRAY' 
      And Typecode = 'COLLECTION'; 

  If Rec_Cnt = 0 Then 
     EXECUTE IMMEDIATE 'CREATE OR REPLACE TYPE vcArray as table of varchar2(32000)'; 
  END IF; 
END;   
/ 

CREATE OR REPLACE TYPE comma_list_agr_type as object 
  ( 
     data  vcArray, 

     static function 
          ODCIAggregateInitialize(sctx IN OUT comma_list_agr_type ) 
          return number, 

     member function 
          ODCIAggregateIterate(self IN OUT comma_list_agr_type , 
                               value IN varchar2 ) 
          return number, 

     member function 
          ODCIAggregateTerminate(self IN comma_list_agr_type, 
                                 returnValue OUT  varchar2, 
                                 flags IN number) 
          return number, 

     member function 
          ODCIAggregateMerge(self IN OUT comma_list_agr_type, 
                             ctx2 IN comma_list_agr_type) 
          return number 
  ); 
/ 


CREATE OR REPLACE TYPE BODY comma_list_agr_type 
  is 

  static function ODCIAggregateInitialize(sctx IN OUT comma_list_agr_type) 
  return number 
  is 
  begin 
      sctx := comma_list_agr_type( vcArray() ); 
      return ODCIConst.Success; 
  end; 

  member function ODCIAggregateIterate(self IN OUT comma_list_agr_type, 
                                       value IN varchar2 ) 
  return number 
  is 
  begin 
      data.extend; 
      data(data.count) := value; 
      return ODCIConst.Success; 
  end; 

  member function ODCIAggregateTerminate(self IN comma_list_agr_type, 
                                         returnValue OUT varchar2, 
                                         flags IN number) 
  return number 
  is 
      l_data varchar2(32000); 
  begin 
      for x in ( select column_value from TABLE(data) order by 1 ) 
      loop 
              l_data := l_data || ',' || x.column_value; 
      end loop; 
      returnValue := ltrim(l_data,','); 
      return ODCIConst.Success; 
  end; 

  member function ODCIAggregateMerge(self IN OUT comma_list_agr_type, 
                                     ctx2 IN comma_list_agr_type) 
  return number 
  is 
  begin -- not really tested ;) 
      for i in 1 .. ctx2.data.count 
      loop 
              data.extend; 
              data(data.count) := ctx2.data(i); 
      end loop; 
      return ODCIConst.Success; 
  end; 
  end; 
/ 

CREATE OR REPLACE FUNCTION comma_list(input varchar2 ) 
  RETURN varchar2 
  PARALLEL_ENABLE AGGREGATE USING comma_list_agr_type; 
/ 

GRANT EXECUTE ON COMMA_LIST to someuser 

【讨论】:

以上是关于在 ORACLE 中,有没有办法使用两个表将多行行连接成一个行,其中最终值用逗号分隔?的主要内容,如果未能解决你的问题,请参考以下文章

oracle中clob字段存入了一段字符串,现在我怎样一行行读取出来

如何借助 Oracle 中的第三张表将数据从源表更新到目标表?

核心数据。加入 2 个具有多对多关系的表?

将多标签图像从云端硬盘上传到 Google Colab

递归地在不同的 xsl 文件中添加一行行

数据库优化一 :sql优化核心