postgresql 使用滞后填充空值,但不支持忽略空值

mfuanj7w  于 2022-11-29  发布在  PostgreSQL
关注(0)|答案(2)|浏览(235)

我有一个表,它看起来像这样:
| 识别码|挣的钱|自启动以来的天数|
| - -|- -|- -|
| 一个|千|一个|
| 一个|二○ ○ ○年|2个|
| 一个|空值| 三个|
| 一个|三千|四个|
| 一个|二○ ○ ○年|五个|
| 2个|千|一个|
| 2个|空值| 2个|
| 2个|100个|三个|
我希望money_earned中没有值的行(这意味着money_earned列当天是空的)将用最后一个已知值填充money_earned,因此它看起来像这样:
| 识别码|挣的钱|自启动以来的天数|
| - -|- -|- -|
| 一个|千|一个|
| 一个|二○ ○ ○年|2个|
| 一个|2000年||
| 一个|三千|四个|
| 一个|二○ ○ ○年|五个|
| 2个|千|一个|
| 2个|一千|2|
| 2个|100个|三个|
我试过查找类似的内容,但是postgresql不支持在滞后窗口函数中忽略空值:(
谢谢你!

jjjwad0x

jjjwad0x1#

LOG()函数适合这个目的,但是在你的例子中你需要得到第一个非空的previous元素。LOG()函数不能处理的。
我建议创建您自己的函数,返回前一个元素的第一个非空值。

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;

注意事项:
如果前一个值为空,则递归调用函数,直到到达最上面的元素;如果最上面的元素也为空,则函数将返回dafult变量中的值。
sqldaddy.io中的演示

gtlvzcf8

gtlvzcf82#

您可以执行以下操作(警告,未经测试!😎):

UPDATE yourtable t1 
SET money_earned = t3.money_earned
FROM yourtable 
LEFT JOIN (SELECT 
                ID,
                MAX(days_since_start) m
           FROM yourtable 
           WHERE ID=t1.ID AND days_since_start<t1.ID) t2 ON t2.ID=i1.ID
INNER JOIN yourtable t3 ON t3.ID=t1.ID and t3.days_since_start = t2.days_since_start
WHERE t1.money_earned is null

相关问题