在 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字段存入了一段字符串,现在我怎样一行行读取出来