我有一个简单的查询:
select * from countries
结果如下:
country_name ------------ Albania Andorra Antigua .....
我想在一行中返回结果,所以像这样:
Albania, Andorra, Antigua, ...
当然,我可以编写一个PL / SQL函数来完成这项工作(我已经在Oracle10g中做到了),但是对于此任务是否有更好的,最好是非Oracle特定的解决方案(或者可能是内置函数) ?
我通常会用它来避免子查询中出现多行,因此,如果一个人有一个以上的公民身份,我不希望他/他在列表中重复。
更新 :我的函数看起来像这样:
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;
这是一种简单的方法,不会产生混乱或创建函数。
create table countries ( country_name varchar2 (100)); insert into countries values ('Albania'); insert into countries values ('Andorra'); insert into countries values ('Antigua'); SELECT SUBSTR (SYS_CONNECT_BY_PATH (country_name , ','), 2) csv FROM (SELECT country_name , ROW_NUMBER () OVER (ORDER BY country_name ) rn, COUNT (*) OVER () cnt FROM countries) WHERE rn = cnt START WITH rn = 1 CONNECT BY rn = PRIOR rn + 1; CSV -------------------------- Albania,Andorra,Antigua 1 row selected.
正如其他人提到的那样,如果您使用的是11g R2或更高版本,则现在可以使用listagg,它更加简单。
select listagg(country_name,', ') within group(order by country_name) csv from countries; CSV -------------------------- Albania, Andorra, Antigua 1 row selected.