Sql server 用以前的非空值填充缺少的数据-但仅限于简单SQL
我有一个值表,需要用前面的非空值填充空格Sql server 用以前的非空值填充缺少的数据-但仅限于简单SQL,sql-server,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
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个月
好的,有很多关于如何使用花式应用程序和CTE以及声明等来实现这一点的帖子。但这里是美中不足的地方
我只能使用拖放ETL工具的功能来实现这一点。这意味着我可以选择字段,可以应用简单的公式(例如Stock为null然后为0),并且可以从下拉列表中选择连接(内部、左外部、右外部)。我不能手工编写自定义子选择、分区覆盖、withs、创建临时表,或者任何比SQL类的第一周更高级的东西。想想MS Access拖放式查询生成器之类的东西
我怎样才能做到这一点?有人吗?好吧,您可以多次自联接到表,然后使用
coalesce
或isnull
或case
。他们都会给你想要的。您需要知道有多少连续的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
该代码应该在大于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
为什么不允许使用任何实际的sql?这似乎是一个奇怪的要求。如果你不能使用任何一种功能,你就会陷入困境。你可能想在这里使用滞后,但我敢打赌你不能用它。你可能会在这里使用一个非常粗糙和缓慢的三角形连接。会让你得到数据,但不会那么快。顺便说一句,我也很感兴趣,为什么你不能像@SeanLange那样使用更高级的tsql。。。这是课程的一部分吗?如果是这样的话,这对于tsql的第1天来说是一个糟糕的例子,因为它是一个GUI驱动的ETL应用程序,它根据您选中的字段和为连接类型选择的下拉列表生成tsql。任何我手工编写的代码都会在我编译代码时被覆盖。我必须使用和IsNull,并与后退1、2、3、4等合并,一直到12个月(一年12个月)。但它奏效了。