在 Oracle 中如何将多行组合成逗号分隔的列表?
我有一个简单的查询:
select * from countries
结果如下:
country_name
------------
Albania
Andorra
Antigua
.....
我想在一行中返回结果,如下所示:
Albania, Andorra, Antigua, ...
当然,我可以编写一个 PL/SQL 函数来完成这项工作(我已经在 Oracle 10g 中做到了),但是是否有更好的、最好是非 Oracle 特定的解决方案(或者可能是内置函数)来完成此任务?
我通常会使用它来避免子查询中出现多行,因此如果一个人拥有多个公民身份,我不希望她/他在列表中重复。
我的问题基于 SQL Server 2005。
更新: 我的函数如下所示:
CREATE OR REPLACE FUNCTION APPEND_FIELD (sqlstr in varchar2, sep in varchar2 ) return varchar2 is
ret varchar2(4000) := '';
TYPE cur_typ IS REF CURSOR;
rec cur_typ;
field varchar2(4000);
begin
OPEN rec FOR sqlstr;
LOOP
FETCH rec INTO field;
EXIT WHEN rec%NOTFOUND;
ret := ret || field || sep;
END LOOP;
if length(ret) = 0 then
RETURN '';
else
RETURN substr(ret,1,length(ret)-length(sep));
end if;
end;
I have a simple query:
select * from countries
with the following results:
country_name
------------
Albania
Andorra
Antigua
.....
I would like to return the results in one row, so like this:
Albania, Andorra, Antigua, ...
Of course, I can write a PL/SQL function to do the job (I already did in Oracle 10g), but is there a nicer, preferably non-Oracle-specific solution (or may be a built-in function) for this task?
I would generally use it to avoid multiple rows in a sub-query, so if a person has more then one citizenship, I do not want her/him to be a duplicate in the list.
My question is based on the similar question on SQL server 2005.
UPDATE:
My function looks like this:
CREATE OR REPLACE FUNCTION APPEND_FIELD (sqlstr in varchar2, sep in varchar2 ) return varchar2 is
ret varchar2(4000) := '';
TYPE cur_typ IS REF CURSOR;
rec cur_typ;
field varchar2(4000);
begin
OPEN rec FOR sqlstr;
LOOP
FETCH rec INTO field;
EXIT WHEN rec%NOTFOUND;
ret := ret || field || sep;
END LOOP;
if length(ret) = 0 then
RETURN '';
else
RETURN substr(ret,1,length(ret)-length(sep));
end if;
end;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
我需要类似的东西并找到了以下解决方案。
I needed a similar thing and found the following solution.
在此示例中,我们将创建一个函数,将逗号分隔的不同行级别 AP 发票保留原因列表放入一个字段中以进行标题级别查询:
In this example we are creating a function to bring a comma delineated list of distinct line level AP invoice hold reasons into one field for header level query:
我总是必须为此编写一些 PL/SQL,或者我只是将一个“,”连接到该字段并复制到编辑器中,然后从列表中删除 CR,从而得到单行。
也就是说,
双向有点啰嗦。
如果您查看 Ask Tom,您会看到大量可能的解决方案,但它们都恢复为类型声明和/或 PL/SQL
问汤姆
I have always had to write some PL/SQL for this or I just concatenate a ',' to the field and copy into an editor and remove the CR from the list giving me the single line.
That is,
A little bit long winded both ways.
If you look at Ask Tom you will see loads of possible solutions but they all revert to type declarations and/or PL/SQL
Ask Tom
您可以使用此查询来执行上述任务,
有关详细信息和分步说明,请访问以下链接
http://oops-solution.blogspot .com/2011/11/sql-server-convert-table-column-data.html
you can use this query to do the above task
for detail and step by step explanation visit the following link
http://oops-solution.blogspot.com/2011/11/sql-server-convert-table-column-data.html
WM_CONCAT
函数(如果包含在 Oracle 11.2 之前的数据库中)或LISTAGG
(从 Oracle 11.2 开始)应该可以很好地实现这一目的。 例如,这会获取架构中以逗号分隔的表名称列表:或
更多详细信息/选项
文档链接
The
WM_CONCAT
function (if included in your database, pre Oracle 11.2) orLISTAGG
(starting Oracle 11.2) should do the trick nicely. For example, this gets a comma-delimited list of the table names in your schema:or
More details/options
Link to documentation
这是一种无需 stragg 或创建函数的简单方法。
正如其他人提到的,如果您使用的是 11g R2 或更高版本,您现在可以使用更简单的 listagg。
Here is a simple way without stragg or creating a function.
As others have mentioned, if you are on 11g R2 or greater, you can now use listagg which is much simpler.
对于 Oracle,您可以使用 LISTAGG
For Oracle you can use LISTAGG
你可以尝试这个查询。
you can try this query.
你也可以使用这个:
You can use this as well:
最快的方法是使用Oracle的collect函数。
您还可以执行以下操作:
访问网站询问 Tom 并搜索 'stragg' 或 'string concatenation' 。 很多
例子。 还有一个未记录的 oracle 函数可以实现您的需求。
The fastest way it is to use the Oracle collect function.
You can also do this:
Visit the site ask tom and search on 'stragg' or 'string concatenation' . Lots of
examples. There is also a not-documented oracle function to achieve your needs.