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;
그WM_CONCAT기능(데이터베이스에 포함되어 있는 경우 Oracle 11.2 이전) 또는LISTAGG(Oracle 11.2를 기동하면) 문제가 잘 해결됩니다.예를 들어 스키마 내의 테이블 이름 목록을 쉼표로 구분하여 가져옵니다.
select listagg(table_name, ', ') within group (order by table_name)
from user_tables;
또는
select wm_concat(table_name)
from user_tables;
다음은 stragg나 함수를 만들지 않고 간단한 방법입니다.
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.
Oracle의 경우 LISTAGG를 사용할 수 있습니다.
이것도 사용할 수 있습니다.
SELECT RTRIM (
XMLAGG (XMLELEMENT (e, country_name || ',')).EXTRACT ('//text()'),
',')
country_name
FROM countries;
이 쿼리를 사용할 수 있습니다.
select listagg(country_name,',') within group (order by country_name) cnt
from countries;
Oracle 수집 기능을 사용하는 가장 빠른 방법입니다.
다음 작업도 수행할 수 있습니다.
select *
2 from (
3 select deptno,
4 case when row_number() over (partition by deptno order by ename)=1
5 then stragg(ename) over
6 (partition by deptno
7 order by ename
8 rows between unbounded preceding
9 and unbounded following)
10 end enames
11 from emp
12 )
13 where enames is not null
사이트를 방문하여 'stragg' 또는 'string concatination'을 검색하십시오. 많은 예제를 참조하십시오.고객의 요구를 충족시키기 위한 문서화되어 있지 않은 Oracle 기능도 있습니다.
저는 비슷한 것이 필요했고 다음과 같은 해결책을 찾았습니다.
select RTRIM(XMLAGG(XMLELEMENT(e,country_name || ',')).EXTRACT('//text()'),',') country_name from
이 예에서는 다른 회선 수준의 AP 청구서 보류 이유를 콤마로 나타낸 목록을 헤더레벨 쿼리용으로1개의 필드에 가져오는 함수를 만들고 있습니다.
FUNCTION getHoldReasonsByInvoiceId (p_InvoiceId IN NUMBER) RETURN VARCHAR2
IS
v_HoldReasons VARCHAR2 (1000);
v_Count NUMBER := 0;
CURSOR v_HoldsCusror (p2_InvoiceId IN NUMBER)
IS
SELECT DISTINCT hold_reason
FROM ap.AP_HOLDS_ALL APH
WHERE status_flag NOT IN ('R') AND invoice_id = p2_InvoiceId;
BEGIN
v_HoldReasons := ' ';
FOR rHR IN v_HoldsCusror (p_InvoiceId)
LOOP
v_Count := v_COunt + 1;
IF (v_Count = 1)
THEN
v_HoldReasons := rHR.hold_reason;
ELSE
v_HoldReasons := v_HoldReasons || ', ' || rHR.hold_reason;
END IF;
END LOOP;
RETURN v_HoldReasons;
END;
항상 이 작업을 위해 PL/SQL을 작성하거나 필드에 ' , , , , 를 연결한 후 편집기에 복사하고 CR 를 목록에서 삭제해야 합니다.
그것은,
select country_name||', ' country from countries
양쪽으로 약간 길게 휘감았다.
Ask Tom을 보면 가능한 솔루션이 많이 표시되지만 모두 유형 선언 및/또는 PL/SQL로 돌아갑니다.
SELECT REPLACE(REPLACE
((SELECT TOP (100) PERCENT country_name + ', ' AS CountryName
FROM country_name
ORDER BY country_name FOR XML PATH('')),
'&<CountryName>', ''), '&<CountryName>', '') AS CountryNames
이 쿼리를 사용하여 위의 작업을 수행할 수 있습니다.
DECLARE @test NVARCHAR(max)
SELECT @test = COALESCE(@test + ',', '') + field2 FROM #test SELECT field2= @test
및 설명은 를 참조하십시오.
http://oops-solution.blogspot.com/2011/11/sql-server-convert-table-column-data.htmlhttpoops-solution.blogspot.com/2011/11/.html
언급URL : https://stackoverflow.com/questions/468990/how-can-i-combine-multiple-rows-into-a-comma-delimited-list-in-oracle
'codememo' 카테고리의 다른 글
| angularjs의 ng-bind 필터를 사용한 후 텍스트 추가 (0) | 2023.02.16 |
|---|---|
| "청취자가 true를 반환하여 비동기 응답을 나타냈지만 응답이 수신되기 전에 메시지 채널이 닫혔습니다." 무슨 의미입니까? (0) | 2023.02.12 |
| Angular.js: .value()는 앱 전체 상수를 설정하고 컨트롤러에서 이를 검색하는 적절한 방법입니까? (0) | 2023.02.12 |
| Wordpress WooCommerce StoreFront 헤더 스타일 제거 (0) | 2023.02.12 |
| 메이븐 의존성 spring-web vs spring-webmvc (0) | 2023.02.12 |