문제

이 질문은 이미 여기에 답이 있습니다.

간단한 쿼리가 있습니다.

select * from countries

다음 결과로 :

country_name
------------
Albania
Andorra
Antigua
.....

결과를 한 줄로 반환하고 싶습니다.

Albania, Andorra, Antigua, ...

물론, 작업을 수행하기 위해 PL/SQL 기능을 작성할 수 있지만 (이미 Oracle 10G에서 수행 했음),이 작업을위한 더 멋지고 바람직하지 않은 비 원래 특이 적 솔루션 (또는 내장 기능이 될 수 있음)이 있습니까? ?

나는 일반적으로 하위 쿼리에서 여러 줄을 피하기 위해 그것을 사용하므로, 사람이 시민권을 가지고 있다면, 나는 그녀가 목록에 중복되기를 원하지 않습니다.

내 질문은 비슷한 질문에 근거합니다 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;
도움이 되었습니까?

해결책

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.

다른 팁

그만큼 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;

자세한 내용/옵션

문서에 대한 링크

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 Collect 기능을 사용하는 것입니다.

당신은 또한 이것을 할 수 있습니다 :

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

사이트를 방문하여 Tom을 방문하여 'stragg'또는 'string concatenation'을 검색하십시오. 많은 예. 또한 귀하의 요구를 달성하기위한 문서화되지 않은 Oracle 기능도 있습니다.

비슷한 것이 필요했고 다음 해결책을 찾았습니다.

select RTRIM(XMLAGG(XMLELEMENT(e,country_name || ',')).EXTRACT('//text()'),',') country_name from  

이 예에서 우리는 쉼표로 묘사 된 별도의 라인 레벨 AP 송장의 목록을 헤더 레벨 쿼리의 한 필드로 가져 오는 기능을 작성합니다.

 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을 써야했거나 a ','필드에 ', 편집자에 복사하고 단일 줄에서 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.html

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top