Announcement

Collapse
No announcement yet.

Nullwerte durch Vorgängerwert ersetzen

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

  • Nullwerte durch Vorgängerwert ersetzen

    Ich habe folgendes Problem: In einer Tabelle sind verschiedene Messwerte gespeichert. Unter anderem sind dort auch mehrere Statuswerte enthalten, welche nur bei einer Änderung übertragen werden, sonst steht da null. Allerdings ist ein Status immer bis zur nächsten Änderung gültig. Jetzt sollte immer der korrekte Status eingetragen sein, nicht nur die Änderung, also so:

    Momentan:

    Status
    ---------
    1 -- Statusänderung
    null
    null
    null
    ...
    2 Statusänderung
    null
    ...
    --------

    Was ich haben will:

    Status
    --------
    1 -- Statusänderung
    1 -- Es wird immer der Status aus der vorhergehenden Zeile übernommen,
    1 -- bis...
    1
    1
    ...
    2 -- ...sich der Status wieder ändert
    2 -- usw.
    2
    2
    ...
    ------

    Meine erste Idee war rekursives Lag/Lead, hab aber dazu nix gefunden. Wahrscheinlich ist die Lösung trivial, und ich komme grade nur nicht drauf. Wer hat ne Idee?

  • #2
    Hat sich schon erledigt. Hab ne Lösung gefunden:

    CASE
    WHEN STATUS is null
    AND lag(Spalte1) over (order by Spalte1) = Spalte1
    THEN last_value(STATUS IGNORE NULLS) over (ORDER BY Spalte1)
    ELSE STATUS
    END AS STATUS

    Comment


    • #3
      <edit>Ich habe gerade man angefangen, drüber nachzudenken und dabei festgestellt, dass das so wie unten beschrieben nur klappt, wenn die Status aufsteigend wären. Also, vergiss es einfach! Ist eben Freitag ...</edit>

      da du sicher für deine Messungen irgendein Sortiermerkmal (Zeitstempel oder so) hast, geht es einfacher so, da die analytischen Funktionen das von dir gewünschte Verhalten schon als Standard liefern:
      [highlight=sql]WITH daten AS (SELECT 1 id, 1 nr_msg,'a' status FROM dual
      UNION ALL
      SELECT 1, 2,NULL FROM dual
      UNION ALL
      SELECT 1, 3,NULL FROM dual
      UNION ALL
      SELECT 1, 4,'b' FROM dual
      UNION ALL
      SELECT 1, 5,NULL FROM dual
      UNION ALL
      SELECT 2, 1,'a' FROM dual)
      SELECT id
      ,nr_msg
      ,MAX(status) OVER (PARTITION BY id ORDER BY nr_msg ) status
      FROM daten
      ORDER BY id,nr_msg;[/highlight]

      Code:
              ID     NR_MSG S
               1          1 a
               1          2 a
               1          3 a
               1          4 b
               1          5 b
               2          1 a

      Gruß

      Ralf
      Zuletzt editiert von ralfb; 25.02.2011, 12:05. Reason: Denkfehler meinerseits ;-)

      Comment


      • #4
        Nun hat's mir doch keine Ruhe gelassen, dass es nicht einfach gehen sollte

        [highlight=sql]WITH daten AS (SELECT 1 id, 1 nr_msg,'b' status FROM dual
        UNION ALL
        SELECT 1, 2,NULL FROM dual
        UNION ALL
        SELECT 1, 3,NULL FROM dual
        UNION ALL
        SELECT 1, 4,'a' FROM dual
        UNION ALL
        SELECT 1, 5,NULL FROM dual
        UNION ALL
        SELECT 1, 6,'c' FROM dual
        UNION ALL
        SELECT 2, 1,'a' FROM dual)
        SELECT id
        ,nr_msg
        ,LAST_VALUE(status ignore nulls ) OVER (PARTITION BY id ORDER BY nr_msg ) status
        FROM daten
        ORDER BY id,nr_msg;
        [/highlight]

        Code:
                ID     NR_MSG S
                 1          1 b
                 1          2 b
                 1          3 b
                 1          4 a
                 1          5 a
                 1          6 c
                 2          1 a
        Schönes Wochenende

        Ralf

        Comment


        • #5
          Danke für Deine Bemühungen, Ralf. Aber meine Lösung funktioniert bestens

          Comment

          Working...
          X