Home > Software design >  Fill nulls with lag, but ignore nulls isn't supported
Fill nulls with lag, but ignore nulls isn't supported

Time:04-30

I have a table which looks like this:

ID money_earned days_since_start
1 1000 1
1 2000 2
1 null 3
1 3000 4
1 2000 5
2 1000 1
2 null 2
2 100 3

I want that rows, without a value in money_earned (which means that the money_earned column was empty that day) - will and fill the money_earned with last known value, so it to look like this:

ID money_earned days_since_start
1 1000 1
1 2000 2
1 2000 3
1 3000 4
1 2000 5
2 1000 1
2 1000 2
2 100 3

I have tried to look up for something like that, but postgresql doesn't support ignore nulls in lag window function :(

thank you!

CodePudding user response:

The LOG() function would be suitable for this purpose, but in your case you need to get first not null previous element. What the LOG() function can't handle.

I suggest creating your own function that would return the first non-null value of the previous element.

CREATE OR REPLACE FUNCTION log_not_null(row_num int, dafult text = '1001') RETURNS text LANGUAGE plpgsql AS $$
DECLARE
  result text; 
  index int;
BEGIN 
  if row_num > 0  then 
      index := row_num - 1;
   else
      return dafult;
   end if;
   result := (select money_earned from my_table  offset index limit 1);
   if result is null then 
     return log_not_null(index); 
   end if;  
   return result;
END
$$;


select id,  log_not_null((row_number() over ())::int) as money_earned, days_since_start from my_table;

Note:

If the previous value is null, then the function is called recursively until it reaches the top element, and if the topmost element is also null, then the function will return the value from the dafult variable.

Demo in DBfiddle

CodePudding user response:

You can do this (warning, untested!

  • Related