Skip to Main Content
  • Questions
  • Get previous non-null value of a column

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question.

Asked: July 10, 2017 - 1:39 pm UTC

Last updated: July 16, 2017 - 7:21 am UTC

Version: 11.2

Viewed 10K+ times! This question is

You Asked

Hi Team,

i have requirement like this , can you help me on this
col1 col2
wk6      1  
wk5      null
wk4     3
wk3      null
wk2      null
wk1      5


i need o/p like below . whenever null value will come it
should take it previous week valu which is not null

o/p
col1 col2
wk6      1  
wk5      3
wk4      3
wk3      5
wk2      5
wk1      5


Thanks
Taj

and Chris said...

Last_value returns the latest value according to your order by and window spec. So you can use that.

But by default this includes null values. So to get the previous non-null value, use the ignore nulls clause:

with rws as (
  select 1 x, 1 y from dual union all
  select 2 x, null y from dual union all
  select 3 x, 10 y from dual union all
  select 4 x, null y from dual union all
  select 5 x, 20 y from dual 
)
  select x, 
         last_value(y) ignore nulls over (
           order by x rows between unbounded preceding and current row
         ) ly
  from   rws;

         X         LY
---------- ----------
         1          1
         2          1
         3         10
         4         10
         5         20

Rating

  (3 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Excellent

MOHAMMED TAJMUL, July 12, 2017 - 7:09 am UTC

Appreciate your quick help.

A reader, July 14, 2017 - 7:55 am UTC


Create table tt ( col1 varchar2(10),col2 varchar2(10)

Insert into tt values('John','abcd')

select *from tt
----------------
col1 col2
---- ---------
john abcd


i want oupput like this

john a
john b
john c
john d

I tried with below code but it's not getting...

unpivot
--------

select *from(select col1, col2 from tt)
unpivot
(col1 for col2 in('a','b','c','d'))

Chris Saxon
July 14, 2017 - 8:59 am UTC

How does this relate to the question asked?

Generalized, especially if not IGNORE NULLS unavailable

Duke Ganote, July 14, 2017 - 4:33 pm UTC

I've had similar situations; the most general approach I know is:

with rws as (
  select 0 x, null y from dual union all
  select 1 x, 'Q' y from dual union all
  select 2 x, null y from dual union all
  select 3 x, 'A' y from dual union all
  select 4 x, null y from dual union all
  select 5 x, 'X' y from dual union all
  select 6 x, null y from dual
),
smoothing AS (
select x, y
     , COALESCE
     ( MIN(CASE WHEN y IS NOT NULL
                THEN x
            END)OVER
          (ORDER BY x DESC)
     , MAX(CASE WHEN y IS NOT NULL
                THEN x
            END)OVER
          (ORDER BY x ASC)
     ) AS Sullenberger#
  from rws
)
select x, y
     , max(y)OVER
        (partition by Sullenberger#)
        as gapfree_y
  from smoothing
 order by 1;

    X Y G
----- - -
    0   Q
    1 Q Q
    2   A
    3 A A
    4   X
    5 X X
    6   X

Connor McDonald
July 16, 2017 - 7:21 am UTC

Nice stuff

More to Explore

Analytics

Analytic SQL got you confused? Check out Connor McDonald's complete video course.