Frage

    

Diese Frage bereits eine Antwort hier:

         

Ich habe eine einfache Abfrage:

select * from countries

mit den folgenden Ergebnissen:

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

Ich möchte die Ergebnisse in einer Reihe zurückzukehren, so wie folgt aus:

Albania, Andorra, Antigua, ...

Natürlich kann ich eine PL / SQL-Funktion schreiben, den Job zu tun (ich habe schon in Oracle 10g), aber gibt es eine schöne, vorzugsweise Nicht-Oracle-spezifische Lösung (oder eine integrierte Funktion sein) für diese Aufgabe?

Ich würde verwendet es in der Regel mehr Zeilen in einer Unterabfrage zu vermeiden, so dass, wenn eine Person mehr als eine Staatsbürgerschaft hat, wie ich sie nicht will / er ein Duplikat in der Liste zu sein.

Meine Frage ist auf der ähnliche Frage basiert auf SQL Server 2005 .

UPDATE : Meine Funktion sieht wie folgt aus:

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;
War es hilfreich?

Lösung

Hier ist eine einfache Art und Weise ohne stragg oder eine Funktion zu schaffen.

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.

Wie andere erwähnt haben, wenn Sie auf 11g R2 oder größer sind, können Sie jetzt listagg verwenden, die viel einfacher ist.

select listagg(country_name,', ') within group(order by country_name) csv
  from countries;

CSV                                                                             
--------------------------
Albania, Andorra, Antigua

1 row selected.

Andere Tipps

Die WM_CONCAT Funktion (falls in der Datenbank enthalten ist, vor Oracle 11.2) oder LISTAGG (ab Oracle 11.2) sollte gut den Trick. Zum Beispiel wird dies eine durch Kommata getrennte Liste der Tabellennamen in Ihrem Schema:

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

oder

select wm_concat(table_name) 
  from user_tables;

Weitere Informationen / Optionen

Link zur Dokumentation

Für Oracle können Sie verwenden LISTAGG

Sie können damit auch:

SELECT RTRIM (
          XMLAGG (XMLELEMENT (e, country_name || ',')).EXTRACT ('//text()'),
          ',')
          country_name
  FROM countries;

Sie können diese Abfrage versuchen.

select listagg(country_name,',') within group (order by country_name) cnt 
from countries; 

Der schnellste Weg ist es Funktion der Oracle sammeln zu verwenden.

Sie können dies auch tun:

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

Besuchen Sie die Website tom fragen und suchen Sie auf ‚stragg‘ oder ‚String-Verkettung‘. Viele Beispiele. Es gibt auch eine nicht dokumentierte Funktion Orakel Ihre Bedürfnisse zu erreichen.

Ich brauchte eine ähnliche Sache und fand die folgende Lösung.

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

In diesem Beispiel sind eine Funktion der Erstellung für Kopfebene Abfrage eine kommagetrennte Liste von verschiedener Leitungsebene AP Rechnung halten Gründe in ein Feld zu bringen:

 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; 

Ich habe immer einige PL / SQL-Code für diese zu schreiben oder ich verketten nur ein ‚‘ auf das Feld und kopieren in einen Editor und entfernen Sie die CR aus der Liste mir die einzige Zeile zu geben.

Das heißt,

select country_name||', ' country from countries

Ein wenig lang in beiden Richtungen außer Atem.

Wenn Sie Fragen schauen Tom finden Sie jede mögliche Lösungen sehen, aber sie alle zurückkehren Erklärungen zu geben und / oder PL / SQL

Tom Frag

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

Sie können diese Abfrage verwenden, um die obige Aufgabe zu tun

DECLARE @test NVARCHAR(max)
SELECT @test = COALESCE(@test + ',', '') + field2 FROM #test SELECT field2= @test

zum Detail und Schritt für Schritt erklärt, besuchen Sie den folgenden Link
http: //oops-solution.blogspot .com / 2011/11 / sQL-Server-convert-table-column-data.html

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top