1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen
  2. Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, Oracle, Sql-Server, Postgres, Access uvm
    Information ausblenden

PIVOT in Abfrage nutzen

Dieses Thema im Forum "Oracle" wurde erstellt von FrenchSpirit, 13 Juni 2017.

  1. FrenchSpirit

    FrenchSpirit Benutzer

    Hallo in die Runde,

    das zweite Problem an einem Tag. Ich habe folgende Tabelle:

    TYP | FELD | FELDWERT
    -----------------------------------
    1 | VORLAUF | 5
    1 | Nachlauf | 10
    2 | VORLAUF | 50
    2 | Nachlauf | 75
    3 | VORLAUF | 2
    3 | Nachlauf | 3


    So habe ich für 3 verschiedene Typen insgesamt 6 Datensätze.

    Ich möchte die Spalten B und C gerne transponieren. In Access hätte ich hierzu eine Kreuztabelle gebaut. In der Forensuche habe ich den Befehl "PIVOT" entdeckt, komme aber selbst mit Oracle / PLSQL: PIVOT Clause nicht komplett klar.

    Das Ergebnis sollte so aussehen:

    TYP | VORLAUF | NACHLAUF
    ---------------------------------------
    1 | 5 | 10
    2 | 50 |75
    3 | 2 | 3

    Folgende (fehlerhafte / unvollständige) Abfrage hab ich bisher:

    SELECT * FROM
    (
    SELECT FELD, FELDWERT
    FROM TABLE
    )
    PIVOT
    (
    MIN(FELDWERT)
    FOR FELD
    IN ( ????????))

    Leider habe ich offensichtlich den PIVOT-Syntax nicht durchstiegen und danke euch vorab für eure Expertenhilfe.

    Gruß,

    Spirit
     
  2. akretschmer

    akretschmer Datenbank-Guru

    ich kenne die Pivot-Syntax von Ora nicht, was aber auch gehen sollte:

    Code:
    test=*# select * from t;
     typ |  feld  | wert
    -----+----------+------
      1 | vorlauf  |  5
      1 | nachlauf |  10
      2 | vorlauf  |  50
      2 | nachlauf |  75
      3 | vorlauf  |  2
      3 | nachlauf |  3
    (6 Zeilen)
    
    test=*# select typ, sum(wert) filter (where feld = 'vorlauf') as vorlauf, sum(wert) filter(where feld = 'nachlauf') as nachlauf from t group by typ order by typ;
     typ | vorlauf | nachlauf
    -----+---------+----------
      1 |  5 |  10
      2 |  50 |  75
      3 |  2 |  3
    (3 Zeilen)
    
    test=*#
    
    Falls FILTER nicht geht:

    Code:
    test=*# select typ, sum(case when feld='vorlauf' then wert else 0 end)  as vorlauf, sum(wert) filter(where feld = 'nachlauf') as nachlauf from t group by typ order by typ;
     typ | vorlauf | nachlauf
    -----+---------+----------
      1 |  5 |  10
      2 |  50 |  75
      3 |  2 |  3
    (3 Zeilen)
    
     
  3. FrenchSpirit

    FrenchSpirit Benutzer

    Hallo, akretschmer,

    danke für die schnelle Hilfe. Mit dem "FILTER"-Befehl habe ich eine Fehlermeldung bzgl. "unexpected FROM".... bekommen.
    Aber mit CASE .... hat es funktioniert:

    select
    EREIGNIS_TYP
    , sum(case when FELD='VORLAUFZEIT' then FELDWERT else '' end) as VORLAUFZEIT
    , sum(case when FELD='NACHLAUFZEIT' then FELDWERT else '' end) as NACHLAUFZEIT
    from EREIGNIS_DEF
    group by EREIGNIS_TYP
    order by EREIGNIS_TYP;


    Leider habe ich neben Vorlaufzeit und Nachlaufzeit noch 20 andere Felder, die ich pro TYP in einer Zeile haben will. Ich hatte gehofft, dass ORACLE automatisch alle unterschiedlichen Felder erkennt (analog der Kreuztabelle in Access)... So muss ich nun für jedes unterschiedliche Feld eine Zeile im Select-Bereich aufbauen. Blöd vor allem dann, wenn mal neue Felder hinzukommen.

    Grüße

    Spirit
     
  4. Monarch

    Monarch Benutzer

    Hallo FrenchSpirit

    hatte vor paar Tagen das gleiche Problem siehe Dynamische Pivot | Datenbank-Forum

    Letztlich ist ein dynamisches Pivot fast unmöglich! Ich schreibe gerade eine Funktion die dynamische Pivots in statische umwandelt und jedesmal bei Änderung eine Funktion neu erstellt. Wenn ich das fertig habe poste ich es hier

    mfg monarch
     
  5. Monarch

    Monarch Benutzer

    Hallo Leute hier die meine Lösung für ein dynamisches Pivot: Bitte beachten das die Tabelle entsprechend durch eure Tabelle ersetzt werden muss (siehe DeinTabelle). Weiter muss festgelegt werden aus welcher Spalte die Pivot - Spalten erstellt werden soll (siehe DeineSpalte)

    CREATE OR REPLACE PROCEDURE IN2LOGPIVOT
    ( s_cur IN OUT SYS_REFCURSOR )
    IS
    TYPE r_cur_t IS REF Cursor;
    r_cur r_cur_t;
    xQuery VARCHAR2(2000);
    cols VARCHAR2(2000);
    BEGIN
    cols :='';
    --Liest alle Wert die im Pivot als Spalten dargestellt werden aus
    for cCols in ( SELECT '''' || DeineSpalte || '''' Spalte
    FROM (SELECT DISTINCT DeineSpalte
    FROM DeinTabelle))
    loop
    if cols is not null then
    cols := cols || ',';
    end if;
    cols := cols || cCols.spalte;
    end loop;

    --Erstellen des Pivot Select
    xQuery := 'SELECT * FROM (SELECT timestamp, Spalte, wert FROM DeinTabelle) PIVOT ( max(wert) FOR Spalte IN (' || Cols || ') ) ORDER BY timestamp';

    --Rückgabe über Cursor
    OPEN s_cur FOR xQuery;


    END;
     
    Walter und drdimitri gefällt das.

Diese Seite empfehlen