填补空白,使用SQL窗口功能结转数据

填补空白,使用SQL窗口功能结转数据,sql,function,window,sql-server-2012,Sql,Function,Window,Sql Server 2012,我试图解决填补数据空白的问题,如果以前的数据存在,则向前推。我可以使用古怪的更新方法解决这个问题,但我正在尝试利用SQL 2012中提供的新SQL窗口功能。我也不想要游标、三角形连接或递归CTE 数据有DayID日期、AssetID和RunningQuantity。我不希望将AssetID的第一个非空RunningQuantity结转,然后我希望将AssetID和RunningQuantity结转,直到RunningQuantity更改,然后将新的RunningQuantity结转。如果Asse

我试图解决填补数据空白的问题,如果以前的数据存在,则向前推。我可以使用古怪的更新方法解决这个问题,但我正在尝试利用SQL 2012中提供的新SQL窗口功能。我也不想要游标、三角形连接或递归CTE

数据有DayID日期、AssetID和RunningQuantity。我不希望将AssetID的第一个非空RunningQuantity结转,然后我希望将AssetID和RunningQuantity结转,直到RunningQuantity更改,然后将新的RunningQuantity结转。如果AssetID发生变化或dayID序列被破坏,即按dayID和dayID排序不是序列中的下一个,则重置新AssetID并重复步骤

以下是包含起始数据、失败尝试和所需结果的sql:


执行此操作的标准SQL方法是:

select *,
       (select top 1 assetid_in
        from test t2
        where t2.dayid_in <= t.dayid_in and
              t2.assetid_in is not null
        order by t2.dayid_in desc
       ) assetid_in2,
       (select top 1 RUNNINGQUANTITY_FL
        from test t2
        where t2.dayid_in <= t.dayid_in and
              t2.RUNNINGQUANTITY_FL is not null
        order by t2.dayid_in desc
       ) running2
from test t;
这是一个SQL小提琴

SQLServer提供了对同一事物进行交叉应用的能力。如果两列的NULL值在同一行中,则可以通过一个交叉应用调用来实现这一点。这就是一个例子

更高级的窗口函数并不能特别帮助您通过为每列使用多个函数来完成所需的操作。Oracle有一个名为ignorenulls的延迟选项。这正是你想要的

select *,
       (select top 1 assetid_in
        from test t2
        where t2.dayid_in <= t.dayid_in and
              t2.assetid_in is not null
        order by t2.dayid_in desc
       ) assetid_in2,
       (select top 1 RUNNINGQUANTITY_FL
        from test t2
        where t2.dayid_in <= t.dayid_in and
              t2.RUNNINGQUANTITY_FL is not null
        order by t2.dayid_in desc
       ) running2
from test t;