首页 > 解决方案 > 获取最后一个非空值?

问题描述

我的数据

是否可以使用最后一个不为空的值(余额)?

在我的数据中,2018-07-31 没有值,所以它应该使用 2018-06-30 的值,即 0。

一行中可以有几行为空。所以它不应该总是占据上面的行。

好的,我将尝试使用 SO 上的格式,但我是新的,所以可能需要一些尝试才能正确:

这是我的数据:

AccountNo EOM Company Balance    
7040    2020-01-31  NF  NULL    
7040    2020-02-29  NF  NULL    
7040    2020-03-31  NF  NULL    
7040    2020-04-30  NF  NULL    
7040    2020-05-31  NF  NULL    
7050    2019-07-31  NF  0.00    
7050    2019-08-31  NF  NULL    
7050    2019-09-30  NF  NULL    
7050    2019-10-31  NF  NULL    
7050    2019-11-30  NF  NULL    
7050    2019-12-31  NF  56224.00    
7050    2020-01-31  NF  NULL    
7050    2020-02-29  NF  0.00

我希望我的结果如下所示。如果该公司的该帐户上有一个,我想要以前的 NON NULL 值。如果没有 NON NULL 值,它应该只是 NULL。

AccountNo   EOM Company Balance
7040    2020-01-31  NF  NULL
7040    2020-02-29  NF  NULL
7040    2020-03-31  NF  NULL
7040    2020-04-30  NF  NULL
7040    2020-05-31  NF  NULL
7050    2019-07-31  NF  0.00
7050    2019-08-31  NF  0.00
7050    2019-09-30  NF  0.00
7050    2019-10-31  NF  0.00
7050    2019-11-30  NF  0.00
7050    2019-12-31  NF  56224.00
7050    2020-01-31  NF  56224.00
7050    2020-02-29  NF  0.00

编辑编号 9000:感谢您的帮助。我仍然习惯 SO,所以我的格式化技巧不是最好的。

标签: sqlsql-server

解决方案


我懂了。您要填写balance最后一个不是null. SQL - 通常 - 支持lag()执行此操作的选项。但是 SQL Server 不(还???)支持这一点。因此,一种方法是横向连接:

select t.*, t2.balance as imputed_balance
from t outer apply
     (select top (1) t2.*
      from t t2
      where t2.AccountNo = t.AccountNo and
            t2.Balance is not null and
            t2.EOM <= t.EOM
      order by t2.EOM desc
     ) t2;

您也可以使用窗口函数来执行此操作。将“组”定义为每个值之前的非 NULL 值的数量。然后将非空值分布在该组上:

select t.*,
       max(balance) over (partition by accountNo, grp) as imputed_balance
from (select t.*,
             count(balance) over (partition by accountNo order by EOM) as grp
      from t
     ) t;

这将比apply每个帐户丢失几个月的速度更快。

update如果您确实想修改数据,这两者都可以合并到语句中。


推荐阅读