使用先前的非空值填充丢失的数据-但仅限于简单的SQL

时间:2019-01-25 21:28:56

标签: sql-server

我有一个值表,并且需要使用先前的非空值来填充空白。

Store  SKU  YearNo  MonthNo  StockQty
001   010C   2018    6       34
001   010C   2018    7       NULL
001   010C   2018    8       NULL
001   010C   2018    9       46
002   010C   2018    6       15
002   010C   2018    7       14
002   010C   2018    8       NULL
002   010C   2018    9       NULL

在上面的示例中,我想用以前的非空值填充空值,因此在SKU 010C的商店001中,第7个月应变为34,第8个月应变为34;在SKU 010C的001商店中,第8和9个月应变为14。

好吧,关于如何用花哨的APPLY和CTE以及语句等来完成此操作的文章很多。但是,美中不足的是……

我必须仅使用拖放ETL工具功能来执行此操作。这意味着我可以选择字段,可以应用简单的公式(例如,当Stock为空然后为0时为CASE),并且可以从下拉列表(内部,左侧和右侧)中选择联接。我不能手工编写自定义的子选择,分区,withs,创建临时表或比SQL类的第一周更高级的东西。认为MS Access拖放查询生成器有点类似。

我该如何完成?有人吗?

2 个答案:

答案 0 :(得分:0)

好吧,您可以自我连接N次表,然后使用coalesceisnullcase。他们都会为您带来想要的东西。您需要知道多少个连续NULL列才能说明所有可能性。

declare @table table (store varchar(3), sku varchar(4), YearNo int, MonthNo int, StockQty int null)
insert into @table
values
('001','010C',2018,6,34),
('001','010C',2018,7,NULL),
('001','010C',2018,8,NULL),
('001','010C',2018,9,46),

('002','010C',2018,6,15),
('002','010C',2018,7,14),
('002','010C',2018,8,NULL),
('002','010C',2018,9,NULL)

select distinct
    t1.store
    ,t1.sku
    ,t1.YearNo
    ,t1.MonthNo
    ,coalesce(t1.StockQty,t2.StockQty,t3.StockQty)
from
    @table t1
    left join @table t2 on
            t2.store = t1.store 
        and t2.YearNo = t1.YearNo 
        and t2.MonthNo = t1.MonthNo -1 
    left join @table t3 on
            t3.store = t1.store 
        and t3.YearNo = t1.YearNo 
        and t3.MonthNo = t1.MonthNo - 2  

或者,作为更新声明...

update t1    
    set StockQty = coalesce(t1.StockQty,t2.StockQty,t3.StockQty)
from
    @table t1
    left join @table t2 on
            t2.store = t1.store 
        and t2.YearNo = t1.YearNo 
        and t2.MonthNo = t1.MonthNo -1 
    left join @table t3 on
            t3.store = t1.store 
        and t3.YearNo = t1.YearNo 
        and t3.MonthNo = t1.MonthNo - 2  

select * from @table

答案 1 :(得分:0)

该代码的工作间隔应大于2个月。 但是,它仍然无法处理一年的切换。

SELECT * INTO #Tbl2 FROM (VALUES
('001','010C',2018,6,34),('001','010C',2018,7,NULL),('001','010C',2018,8,NULL),('001','010C',2018,9,46),
('002','010C',2018,6,15),('002','010C',2018,7,14),('002','010C',2018,8,NULL),('002','010C',2018,9,NULL))
x (Store,SKU,YearNo,MonthNo,StockQty)

SELECT t.Store, t.SKU, t.YearNo, t.MonthNo
    , StockQty = ISNULL(t.StockQty,t3.StockQty)
FROM #Tbl2 as t
OUTER APPLY (
    SELECT MonthNo = MAX(ti.MonthNo) 
    FROM #Tbl2 as ti
    WHERE t.Store = ti.Store and t.SKU = ti.SKU and t.YearNo = ti.YearNo
        and t.MonthNo > ti.MonthNo and ti.StockQty is not null
) as t2
LEFT JOIN #Tbl2 as t3 ON t2.MonthNo = t3.MonthNo 
    and t.Store = t3.Store and t.SKU = t3.SKU and t.YearNo = t3.YearNo