2014-11-17 17 views
9

Ich habe eine Tabelle mit 4 Spalten: Artikel, Jahr, Monat, Menge. Einige der Werte für Amount sind NULL und wenn das passiert, möchte ich diese Werte mit dem vorherigen Betragswert füllen, der nicht null ist. Ich kann das leicht mit der LAG-Funktion machen, wenn es nur einen Nullwert gibt, aber wenn es mehrere hintereinander gibt, bin ich mir nicht sicher, wie ich es angehen soll. Unten ist ein Beispiel dafür, was die Tabelle wie mit einer zusätzlichen Spalte aussehen könnte für das, was ich in meiner Anfrage hinzufügen möchten:Füllen Null-Werte mit letzten Nicht-Null-Betrag - Oracle SQL

Item | Year | Month | Amount | New_Amount 
AAA | 2013 | 01 | 100 | 100 
AAA | 2013 | 02 |  | 100 
AAA | 2013 | 03 | 150 | 150 
AAA | 2013 | 04 | 125 | 125 
AAA | 2013 | 05 |  | 125 
AAA | 2013 | 06 |  | 125 
AAA | 2013 | 07 |  | 125 
AAA | 2013 | 08 | 175 | 175 

ich zwei Ideen hatte, die ich nicht, was zu arbeiten scheinen, um zu produzieren I wollen. Zuerst wollte ich LAG verwenden, aber dann bemerkte ich, wenn mehrere NULL-Werte in einer Zeile vorhanden sind, wird dies nicht ausreichen. Als nächstes würde ich FIRST_VALUE verwenden, aber das würde in dieser Situation nicht helfen, wo es eine Null gibt, gefolgt von Werten gefolgt von mehr Nullen. Gibt es eine Möglichkeit, FIRST_VALUE oder eine andere ähnliche Funktion zu verwenden, um den letzten Nicht-Null-Wert abzurufen?

Antwort

7

last_value mit IGNORE NULLS funktioniert in Oracle 10g:

select item, year, month, amount, 
     last_value(amount ignore nulls) 
     over(partition by item 
       order by year, month 
       rows between unbounded preceding and 1 preceding) from tab; 

rows between unbounded preceding and 1 preceding setzt das Fenster für analytische Funktion.

In diesem Fall Oracle für LAST_VALUE innerhalb der Gruppe in PARTITION BY (das gleiche Element) vom Anfang (UNBOUNDED VORHERGEHENDEN) bis aktueller Zeile definiert sucht - 1 (1 oben) für LEAD

Es ist ein gemeinsamer Ersatz/LAG mit IGNORE NULLS in Oracle 10g

jedoch wenn Sie mit Oracle 11g Sie LAG von der Gordon Linoff Antwort (es gibt einen kleinen Tippfehler mit "ignorieren NULL-Werte")

+0

Danke, das hat perfekt funktioniert, der letzte Teil zwischen unbeschränktem Vorangehen und Vorangehen ist etwas, was ich nicht ganz verstehe, würde es dir etwas ausmachen zu erklären, was das ist? – user1723699

+0

@ user1723699 Ich habe meine Antwort aktualisiert. Sie können Oracle-Dokumentation über WINDOWING in analytischen Funktionen lesen. – Multisync

+0

Danke, ich bin kurz mit dem Fenster vertraut, lerne aber immer noch, da ich mich vollkommen autodidaktisch auskenne und keinen starken Programmierhintergrund habe. Das funktionierte wie ein Zauber, aber ich schätze es sehr. – user1723699

7

Hier ist ein Ansatz. Zählen Sie die Anzahl der Nicht-Null-Werte vor einer bestimmten Zeile. Dann ist diese Verwendung als Gruppe für eine Fensterfunktion:

select t.item, t.year, t.month, t.amount, 
     max(t.amount) over (partition by t.item, grp) as new_amount 
from (select t.*, 
      count(Amount) over (Partition by item order by year, month) as grp 
     from table t 
    ) t; 

In Oracle Version 11+ können Sie ignore nulls für lag() und lead() verwenden:

select t.item, t.year, t.month, t.amount, 
     lag(t.amount ignore nulls) over (partition by t.item order by year, month) as new_amount 
from table t 
+0

+1 Die Zeit nutzen, kann ich nahm, um es zu lesen .. Es gibt eine Antwort .. Sie halten mich überraschen! :) –

+0

Das ist super, vielen Dank! – user1723699