填补空白,使用SQL Windowing函数传送数据

时间:2014-02-19 17:36:36

标签: sql function window sql-server-2012

我正在尝试解决填补数据空白的问题,提取以前的数据(如果存在。我可以使用“quirky update”方法解决它但我正在尝试利用SQL 2012中提供的新SQL窗口函数我也不想要游标或三角形连接或递归CTE。

数据包含DayID(日期),AssetID和RunningQuantity。我不希望在AssetID的第一个非null RunningQuantity之前继续运行,然后我想继续使用AssetID和RunningQuantity直到RunningQuantity更改,然后向前传递新的RunningQuantity。如果AssetID更改或dayID序列被破坏,即。按日期顺序排列的日期和日期不是下一个,重新设置新的AssetID并重复步骤。

这是带有起始数据的sql,尝试失败,然后是期望的结果:


if OBJECT_ID('tempdb..#test') is not null
    drop table #test
create table #test (
    DayID_in int,
    AssetID_in int,
    RunningQuantity_fl float )

insert into #test (DayID_in,AssetID_in,RunningQuantity_fl) values (77420,NULL,NULL) insert into #test (DayID_in,AssetID_in,RunningQuantity_fl) values (77421,NULL,NULL) insert into #test (DayID_in,AssetID_in,RunningQuantity_fl) values (77422,317728,2841.716) insert into #test (DayID_in,AssetID_in,RunningQuantity_fl) values (77423,NULL,NULL) insert into #test (DayID_in,AssetID_in,RunningQuantity_fl) values (77424,317728,2641.677) insert into #test (DayID_in,AssetID_in,RunningQuantity_fl) values (77425,317728,1688.731) insert into #test (DayID_in,AssetID_in,RunningQuantity_fl) values (77426,NULL,NULL) insert into #test (DayID_in,AssetID_in,RunningQuantity_fl) values (77427,NULL,NULL) insert into #test (DayID_in,AssetID_in,RunningQuantity_fl) values (77420,NULL,NULL) insert into #test (DayID_in,AssetID_in,RunningQuantity_fl) values (77421,NULL,NULL) insert into #test (DayID_in,AssetID_in,RunningQuantity_fl) values (77422,317744,1527.03) insert into #test (DayID_in,AssetID_in,RunningQuantity_fl) values (77423,NULL,NULL) insert into #test (DayID_in,AssetID_in,RunningQuantity_fl) values (77424,317744,1544.748) insert into #test (DayID_in,AssetID_in,RunningQuantity_fl) values (77425,NULL,NULL) insert into #test (DayID_in,AssetID_in,RunningQuantity_fl) values (77426,317744,1544.748) insert into #test (DayID_in,AssetID_in,RunningQuantity_fl) values (77427,317744,1706.072) insert into #test (DayID_in,AssetID_in,RunningQuantity_fl) values (77428,NULL,NULL) insert into #test (DayID_in,AssetID_in,RunningQuantity_fl) values (77429,317745,7324.573) insert into #test (DayID_in,AssetID_in,RunningQuantity_fl) values (77430,NULL,NULL) insert into #test (DayID_in,AssetID_in,RunningQuantity_fl) values (77431,NULL,NULL)

select b.DayID_in,b.AssetID_in,b.RunningQuantity_fl,PreviousQTY=lag(b.runningQuantity_fl) over (Partition by b.assetID_in order by b.AssetID_in,b.dayID_in) from #test b

if OBJECT_ID('tempdb..#desiredResult') is not null drop table #desiredResult create table #desiredResult ( DayID_in int, AssetID_in int, RunningQuantity_fl float )

insert into #desiredResult (DayID_in,AssetID_in,RunningQuantity_fl) values (77420,NULL,NULL) insert into #desiredResult (DayID_in,AssetID_in,RunningQuantity_fl) values (77421,NULL,NULL) insert into #desiredResult (DayID_in,AssetID_in,RunningQuantity_fl) values (77422,317728,2841.716) insert into #desiredResult (DayID_in,AssetID_in,RunningQuantity_fl) values (77423,317728,2841.716) insert into #desiredResult (DayID_in,AssetID_in,RunningQuantity_fl) values (77424,317728,2641.677) insert into #desiredResult (DayID_in,AssetID_in,RunningQuantity_fl) values (77425,317728,1688.731) insert into #desiredResult (DayID_in,AssetID_in,RunningQuantity_fl) values (77426,317728,1688.731) insert into #desiredResult (DayID_in,AssetID_in,RunningQuantity_fl) values (77427,317728,1688.731) insert into #desiredResult (DayID_in,AssetID_in,RunningQuantity_fl) values (77420,NULL,NULL) insert into #desiredResult (DayID_in,AssetID_in,RunningQuantity_fl) values (77421,NULL,NULL) insert into #desiredResult (DayID_in,AssetID_in,RunningQuantity_fl) values (77422,317744,1527.03) insert into #desiredResult (DayID_in,AssetID_in,RunningQuantity_fl) values (77423,317744,1527.03) insert into #desiredResult (DayID_in,AssetID_in,RunningQuantity_fl) values (77424,317744,1544.748) insert into #desiredResult (DayID_in,AssetID_in,RunningQuantity_fl) values (77425,317744,1544.748) insert into #desiredResult (DayID_in,AssetID_in,RunningQuantity_fl) values (77426,317744,1544.748) insert into #desiredResult (DayID_in,AssetID_in,RunningQuantity_fl) values (77427,317744,1706.072) insert into #desiredResult (DayID_in,AssetID_in,RunningQuantity_fl) values (77428,317744,1706.072) insert into #desiredResult (DayID_in,AssetID_in,RunningQuantity_fl) values (77429,317745,7324.573) insert into #desiredResult (DayID_in,AssetID_in,RunningQuantity_fl) values (77430,317744,7324.573) insert into #desiredResult (DayID_in,AssetID_in,RunningQuantity_fl) values (77431,317744,7324.573)

select * from #desiredResult

1 个答案:

答案 0 :(得分:0)

执行此操作的“标准”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;

Here是一个SQL小提琴。

SQL Server提供了对同一事物进行交叉申请的能力。如果两列的cross apply值位于同一行,则可以通过一次NULL调用执行此操作。 Here就是一个例子。

更高级的窗口函数没有特别的帮助(您可以为每列执行多个函数所需的操作)。 Oracle在lag()上有一个名为ignore nulls的选项。这完全符合您的要求。