2014-11-17 12 views
9

Ho una tabella con 4 colonne: Elemento, Anno, Mese, Quantità. Alcuni valori di Amount sono nulli e quando ciò accade, voglio riempire quei valori con il valore Amount precedente che non è nullo. Posso farlo facilmente con la funzione LAG quando c'è solo un valore nullo, ma quando ci sono più file in una riga non sono sicuro di come affrontarlo. Di seguito è riportato un esempio di ciò che il tavolo potrebbe essere simile con una colonna aggiunto per quello che voglio aggiungere la mia domanda:Immettere valori null con l'ultimo importo non null - 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 

ho avuto due idee che non riesco a mettersi al lavoro per la produzione di quello che ho volere. In primo luogo stavo per usare il LAG ma poi ho notato che quando ci sono più valori nulli in una riga non lo soddisferà. Successivamente stavo per utilizzare FIRST_VALUE ma questo non sarebbe d'aiuto in questa situazione in cui c'è un null seguito da valori seguiti da più null. C'è un modo per utilizzare FIRST_VALUE o un'altra funzione simile per recuperare l'ultimo valore non null?

risposta

7

last_value con IGNORE NULLS funziona bene 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 imposta la finestra per la funzione di analisi.

In questo caso Oracle sta cercando LAST_VALUE all'interno del gruppo definito in PARTITION BY (stesso articolo) fin dall'inizio (UNBOUNDED precedente) finché riga corrente - 1 (1 precedente)

È un sostituto comune per il piombo/LAG con iGNORA NULLS in Oracle 10g

Tuttavia, se si sta utilizzando Oracle 11g è possibile utilizzare GAL dalla risposta del Gordon Linoff (c'è un piccolo errore di battitura con "ignora i null")

+0

Grazie, questo ha funzionato perfettamente, l'ultima parte tra illimitato precedente e 1 precedente è qualcosa che non capisco completamente, ti dispiacerebbe spiegare che cosa fa? – user1723699

+0

@ user1723699 Ho aggiornato la mia risposta. È possibile leggere la documentazione Oracle su WINDOWING nelle funzioni analitiche. – Multisync

+0

Grazie, ho una breve familiarità con il windowing, ma sto ancora imparando, dato che sono completamente autodidatta e non ho un forte background di programmazione. Questo ha funzionato come un fascino, quindi lo apprezzo molto. – user1723699

7

Ecco un approccio. Contare il numero di valori non nulli prima di una data riga. Quindi utilizzare questo come un gruppo per una funzione finestra:

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 versione 11+, è possibile utilizzare ignore nulls per lag() e lead():

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 il tempo che ho ho preso a leggerlo .. C'è una risposta .. Continua a sorprendermi! :) –

+0

È fantastico, grazie mille! – user1723699