Announcement

Collapse
No announcement yet.

Strings aus mehreren zeilen verbinden

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Strings aus mehreren zeilen verbinden

    Hi also ich nutze Oracle und habe auch die Möglichkeit PL/SQL zu nutzen
    ich möchte jetzt eine select anweisung in der mir strings verbunden werden, wie es bei zahlen SUM gibt.
    so siehts bei mir aus
    table_name
    ID description ....
    1 record1
    2 record2
    3 record3
    1 record4
    2 record5
    1 record6

    und aussehen soll es so
    1 record1, record4, record6
    2 record2, record5
    3 record 3

    nochaml in worte vielleicht
    ich hab eine ID (keine vortlaufende zahl) von nem auftrag und die kommt öfter (ist einfach so) vor und kann mehreren beschreibungen haben, muss aber nicht
    jetzt will ich aber nicht dass der auftrag 3 mal untereinander steht wenn ich nach ihm such und in der letzten spalte dann die 3 verschiedenen beschreibungen sondern, dass die ID einmal angezeigt wird und die beschreibungen hintereinander in einem feld stehen.
    wenn ihr ne lösung habt, dann bitte so erklären dass es auch dumme verstehen.
    ach ja die lösung sollte keine daten in der tabelle selbst verändern wenn möglich

    danke schonmal
    mfg

    Falk

  • #2
    Originally posted by falkh View Post
    Hi also ich nutze Oracle und habe auch die Möglichkeit PL/SQL zu nutzen
    ich möchte jetzt eine select anweisung in der mir strings verbunden werden, wie es bei zahlen SUM gibt.
    so siehts bei mir aus
    table_name
    ID description ....
    1 record1
    2 record2
    3 record3
    1 record4
    2 record5
    1 record6

    und aussehen soll es so
    1 record1, record4, record6
    2 record2, record5
    3 record 3



    danke schonmal
    mfg

    Falk

    Hallo,

    anbei ein Beispiel für Oracle..

    Code:
    CREATE OR REPLACE TYPE vcArray AS TABLE OF VARCHAR2 (4000)
    /
    CREATE OR REPLACE TYPE string_agg_type AS OBJECT (
       DATA   vcArray,
       STATIC FUNCTION ODCIAggregateInitialize (sctx IN OUT string_agg_type)
          RETURN NUMBER,
       MEMBER FUNCTION ODCIAggregateIterate (
          SELF    IN OUT   string_agg_type,
          VALUE   IN       VARCHAR2
       )
          RETURN NUMBER,
       MEMBER FUNCTION ODCIAggregateTerminate (
          SELF          IN       string_agg_type,
          returnValue   OUT      VARCHAR2,
          flags         IN       NUMBER
       )
          RETURN NUMBER,
       MEMBER FUNCTION ODCIAggregateMerge (
          SELF   IN OUT   string_agg_type,
          ctx2   IN       string_agg_type
       )
          RETURN NUMBER
    );
    /
    
    CREATE OR REPLACE TYPE BODY string_agg_type
    IS
       STATIC FUNCTION ODCIAggregateInitialize (sctx IN OUT string_agg_type)
          RETURN NUMBER
       IS
       BEGIN
          sctx := string_agg_type (vcArray ());
          RETURN ODCIConst.Success;
       END;
       MEMBER FUNCTION ODCIAggregateIterate (
          SELF    IN OUT   string_agg_type,
          VALUE   IN       VARCHAR2
       )
          RETURN NUMBER
       IS
       BEGIN
          DATA.EXTEND;
          DATA (DATA.COUNT) := VALUE;
          RETURN ODCIConst.Success;
       END;
       MEMBER FUNCTION ODCIAggregateTerminate (
          SELF          IN       string_agg_type,
          returnValue   OUT      VARCHAR2,
          flags         IN       NUMBER
       )
          RETURN NUMBER
       IS
          l_data   VARCHAR2 (4000);
       BEGIN
          FOR x IN (SELECT   COLUMN_VALUE
                        FROM TABLE (DATA)
                    ORDER BY 1)
          LOOP
             l_data := l_data || ',' || x.COLUMN_VALUE;
          END LOOP;
    
          returnValue := LTRIM (l_data, ',');
          RETURN ODCIConst.Success;
       END;
       MEMBER FUNCTION ODCIAggregateMerge (
          SELF   IN OUT   string_agg_type,
          ctx2   IN       string_agg_type
       )
          RETURN NUMBER
       IS
       BEGIN                                               -- not really tested ;)
          FOR i IN 1 .. ctx2.DATA.COUNT
          LOOP
             DATA.EXTEND;
             DATA (DATA.COUNT) := ctx2.DATA (i);
          END LOOP;
    
          RETURN ODCIConst.Success;
       END;
    END;
    /
    
    CREATE OR REPLACE FUNCTION stragg (input VARCHAR2)
       RETURN VARCHAR2 PARALLEL_ENABLE
       AGGREGATE USING string_agg_type;
    /
    
    CREATE TABLE example_pivot
        (column_1                       VARCHAR2(20),
        column_2                       VARCHAR2(20))
    /
    INSERT INTO example_pivot
         VALUES ('VW', 'Polo')
    /
    INSERT INTO example_pivot
         VALUES ('VW', 'Golf')
    /
    INSERT INTO example_pivot
         VALUES ('VW', 'Touran')
    /
    INSERT INTO example_pivot
         VALUES ('BMW', '320')
    /
    INSERT INTO example_pivot
         VALUES ('BMW', '540')
    /
    INSERT INTO example_pivot
         VALUES ('Audi', 'A4')
    /
    INSERT INTO example_pivot
         VALUES ('Audi', 'A6')
    /
    
    
    SELECT   COLUMN_1, stragg (COLUMN_2) COLUMN_2
        FROM EXAMPLE_PIVOT
    GROUP BY COLUMN_1
    /

    Gruss

    Comment


    • #3
      ab ~ 10g könnte man statt stragg auch noch den sys_connect_by_path verwenden (in Kombination mit analytics), was eine reine sql-Lösung wäre, aber nicht unbedingt leichter zu verstehen ...

      vgl. http://asktom.oracle.com/pls/asktom/...68891781372516

      PHP Code:
      ops$tkyte%ORA10GR2SELECT customer,
        
      2  MAX(LTRIMsys_connect_by_pathproduct',' ) ,  ','))  prod_str
        3  FROM
        4  
      (
        
      5    SELECT customerproduct,
        
      6           row_number() over (PARTITION BY customer ORDER BY productrn
        7    FROM 
      (select distinct customerproduct from STAGE)
        
      8  )
        
      9  START WITH rn 1
       10  CONNECT BY customer 
      PRIOR customer AND  PRIOR  rn  rn -1
       11  GROUP BY customer
      ;

      CU PROD_STR
      -- ----------------------------------------
      C2 P2,P3
      C1 P1
      ,P2,P3
      C3 P1 
      Gruß

      MP
      http://martinpreiss.blogspot.com/

      Comment


      • #4
        man kann notfalls auch die (undokumentierte) aber unheimlich praktische Funktion wm_concat verwenden (ich habe anstatt die Tabelle zu bauen mal nur SELECTs verwendet)
        Code:
        with a as 
        (
        select 1 id, 'record1' rec from dual
        UNION ALL
        select 2, 'record2' from dual
        UNION ALL
        select 3, 'record3' from dual
        UNION ALL
        select 1, 'record4' from dual
        UNION ALL
        select 2, 'record5' from dual
        UNION ALL
        select 1, 'record6' from dual
        )
        select id, wm_concat(rec) ges from a
        group by id
        gibt als Ergebnis exakt:
        Code:
        ID	GES
        1	record1,record4,record6
        2	record2,record5
        3	record3

        Comment

        Working...
        X