116

簡単なクエリがあります:

select * from countries

次の結果が得られます。

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

結果を 1 行で返したいので、次のようにします。

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;
4

11 に答える 11

124

WM_CONCAT関数(データベースに含まれている場合、Oracle 11.2より前)または(LISTAGGOracle 11.2以降)はうまく機能するはずです。たとえば、これはスキーマ内のテーブル名のカンマ区切りのリストを取得します。

select listagg(table_name, ', ') within group (order by table_name) 
  from user_tables;

また

select wm_concat(table_name) 
  from user_tables;

詳細・オプション

ドキュメントへのリンク

于 2011-07-27T17:12:51.633 に答える
96

これは、ストラッグや関数の作成を行わない簡単な方法です。

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.
于 2009-01-22T20:24:40.910 に答える
21

Oracleの場合、LISTAGGを使用できます

于 2011-08-23T17:21:22.643 に答える
20

これも使用できます:

SELECT RTRIM (
          XMLAGG (XMLELEMENT (e, country_name || ',')).EXTRACT ('//text()'),
          ',')
          country_name
  FROM countries;
于 2010-10-26T19:02:42.923 に答える
19

このクエリを試すことができます。

select listagg(country_name,',') within group (order by country_name) cnt 
from countries; 
于 2013-03-15T13:14:31.140 に答える
2

この例では、個別の明細レベルの 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; 
于 2012-11-16T22:09:05.787 に答える
2

同様のことが必要で、次の解決策が見つかりました。

select RTRIM(XMLAGG(XMLELEMENT(e,country_name || ',')).EXTRACT('//text()'),',') country_name from  
于 2010-11-26T06:24:16.470 に答える
0
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
于 2012-08-27T06:10:43.653 に答える
-4

このクエリを使用して上記のタスクを実行できます

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

于 2011-11-04T12:04:17.207 に答える