Announcement

Collapse
No announcement yet.

Complexere Select Abfrage

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

  • Complexere Select Abfrage

    Hallo die Damen und Herren,
    ich bin nun nicht direkt ein neuling was Datenbanken angeht aber irgendwie bekomme ich dieses Problem nicht gelöst.

    Ich habe eine Tabelle die folgende Struktur aufweist
    ------------------
    Auto | Modell |
    ------------------
    VW | Polo |
    ------------------
    VW |Golf |
    ------------------
    VW | Touran|
    ------------------
    BMW |330d |
    -------------------
    nun möchte ich ein SQL Statement verfassen das mir folgendes zurückliefert

    VW: Polo, Golf, Touran
    BMW: 330d,......

    Ist es möglich in Oracle die Tabellenstruktur um 90° zu drehen?
    Ich finde irgendwie keine Lösung die nicht über variablen ist bzw. eine Stored Procedure.
    Wenn jemand eine Idee oder einen Lösungsansatz hat wäre ich sehr dankbar.

  • #2
    Originally posted by Lifestyler View Post
    Hallo die Damen und Herren,
    ich bin nun nicht direkt ein neuling was Datenbanken angeht aber irgendwie bekomme ich dieses Problem nicht gelöst.

    Ist es möglich in Oracle die Tabellenstruktur um 90° zu drehen?
    Ich finde irgendwie keine Lösung die nicht über variablen ist bzw. eine Stored Procedure.
    Wenn jemand eine Idee oder einen Lösungsansatz hat wäre ich sehr dankbar.
    - Hallo, habe gerade keine Zeit, ein Beispiel zu machen. Info's darüber findest du hier :

    http://asktom.oracle.com/pls/asktom/...0:1:0::NO:RP::

    - Wenn du Oracle 11g verwendest, könntest du das neue PIVOT Schlüsselwort direkt in SQL benutzen


    Gruss

    Comment


    • #3
      ne ist leider noch 9i kann aber auch 10 benutzten 11 ist aber noch nicht realisiert bei mir

      Comment


      • #4
        Originally posted by Lifestyler View Post
        ne ist leider noch 9i kann aber auch 10 benutzten 11 ist aber noch nicht realisiert bei mir
        - Ok, ist vielleicht eine etwas "komplexere" Lösung, funktioniert dafür auch sehr generell :-)

        1. Zuerst ein paar Vorbereitungen...

        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   
              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;
        /
        2. Dein Beispiel :

        Code:
        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')
        /

        3. Und nun verwenden wir die Funktion...


        Code:
        SELECT   COLUMN_1, stragg (COLUMN_2) COLUMN_2
            FROM EXAMPLE_PIVOT
        GROUP BY COLUMN_1
        /
        4. Das Resultat :

        Code:
        COLUMN_1             COLUMN_2
        Audi                     A4,A6
        BMW                  320,540
        VW                   Golf,Polo,Touran

        Gruss

        Comment


        • #5
          Wie gesagt, ohne PL (oder auch Typen) geht es nicht in Oracle ohne das du die Obergrenze der Anzahl modelle festlegst.
          Bei meinem Beispiel sind es fünf:

          WITH temp AS ( SELECT 'VW' Marke , 'K„fer 1300' Model from dual union
          SELECT 'VW' Marke , 'Bulli' Model from dual union
          SELECT 'VW' Marke , 'Passat' Model from dual union
          SELECT 'VW' Marke , '1600' Model from dual union
          SELECT 'Audi' Marke , 'A3' Model from dual union
          SELECT 'Audi' Marke , 'A4' Model from dual union
          SELECT 'Audi' Marke , 'A6' Model from dual union
          SELECT 'Audi' Marke , 'A8' Model from dual union
          SELECT 'Audi' Marke , 'A6 Kombi' Model from dual union
          SELECT 'Audi' Marke , 'A4 Sport' Model from dual union
          SELECT 'VW' Marke , 'K„fer 1200' Model from dual union
          SELECT 'BMW' Marke , 'M3' Model from dual
          )
          SELECT marke
          , max(DECODE(rank,1,model||';',NULL) ) F1
          , max(DECODE(rank,2,model||';',NULL) ) F2
          , max(DECODE(rank,3,model||';',NULL) ) F3
          , max(DECODE(rank,3,model||';',NULL) ) F4
          , max(DECODE(rank,4,model||';',NULL) ) F5
          , max(DECODE(rank,6,'more;',NULL) ) last
          FROM (SELECT marke,model, rank() OVER ( PARTITION BY marke ORDER BY marke,model ) rank FROM temp ORDER BY marke,model)
          GROUP BY marke
          ORDER BY marke
          ;

          Comment


          • #6
            Originally posted by uminky View Post
            Wie gesagt, ohne PL (oder auch Typen) geht es nicht in Oracle ohne das du die Obergrenze der Anzahl modelle festlegst.
            ;
            - Oder du verwendest Oracle 11 und dort das neue PIVOT-Konstrukt...


            Gruss

            Comment

            Working...
            X