請幫助我提出想法(最好是CTE)以儘可能高效地解決此問題。使用CTE或任何有效的遞歸填充計算
因此...在示出的表中,在列「值」的細胞,其是紅是已知值0和突出顯示的果嶺與所示旁邊的公式計算的值。 我正在嘗試查看CTE是否可能。
這就像最後一次已知的值及其相應的間隔;下一個已知的值和相應的間隔;以及計算值的間隔;所有這些都是用來找到那個實習生將以同樣的方式用於下一個未知值的值。
請幫助我提出想法(最好是CTE)以儘可能高效地解決此問題。使用CTE或任何有效的遞歸填充計算
因此...在示出的表中,在列「值」的細胞,其是紅是已知值0和突出顯示的果嶺與所示旁邊的公式計算的值。 我正在嘗試查看CTE是否可能。
這就像最後一次已知的值及其相應的間隔;下一個已知的值和相應的間隔;以及計算值的間隔;所有這些都是用來找到那個實習生將以同樣的方式用於下一個未知值的值。
這裏是我想出了(storevalue是開始表在你的例子)
with knownvalues as (
select store, shipNtrvl,value
from storevalue where Value is not null
), valueranges as
(
select
k.store,
k.ShipNtrvl as lowrange,
MIN(s.ShipNtrvl) as highrange,
(select value from storevalue where store = k.store and ShipNtrvl = MIN(s.shipNtrvl))-
(select value from storevalue where store = k.store and ShipNtrvl = k.ShipNtrvl) as term1,
MIN(s.ShipNtrvl) - k.ShipNtrvl as term2,min(k.Value) as lowval
from knownvalues k
join storevalue s on s.Value is not null and s.store= k.store and s.ShipNtrvl > k.ShipNtrvl
group by k.store, k.shipntrvl
)
select s.store,s.ShipNtrvl,v.term1/v.term2*(s.ShipNtrvl-v.lowrange)+ v.lowval as value
from storevalue s join valueranges v on v.store = s.store and s.ShipNtrvl between v.lowrange and v.highrange
where s.Value is null
union
select * from storevalue where value is not null
就改變選擇到一個更新的值寫入到表中。
這是一個解決方案。
希望它有幫助。 :)
;with testdata(store,shipntrvl,value)
as
(
select 'abc', 1, 0.56
union all
select 'abc', 5, null
union all
select 'abc', 10, 0.63
union all
select 'abc', 15, null
union all
select 'abc', 20, null
union all
select 'abc', 25, null
union all
select 'abc', 30, 0.96
union all
select 'xyz', 1, 0.36
union all
select 'xyz', 5, 0.38
union all
select 'xyz', 10, null
union all
select 'xyz', 15, 0.46
union all
select 'xyz', 20, null
union all
select 'xyz', 25, null
union all
select 'xyz', 30, 0.91
)
,calc
as
(
select *
,ROW_NUMBER() OVER(partition by store order by shipntrvl) as row_no
from testdata
)
,extra
as
(
select *
,(select top 1 row_no
from calc c2
where c2.row_no < c1.row_no
and c1.value is null
and c2.value is not null
and c1.store = c2.store
order by c2.row_no desc) as prev_nr
,(select top 1 row_no
from calc c2
where c2.row_no > c1.row_no
and c1.value is null
and c2.value is not null
and c1.store = c2.store
order by c2.row_no asc) as next_nr
from calc c1
)
select c.store
,c.shipntrvl
,c.value
,isnull(c.value,
(cnext.value-cprev.value)/
(cnext.shipntrvl-cprev.shipntrvl)*
(c.shipntrvl-cprev.shipntrvl)+cprev.value
) as calculated_value
from calc c
join extra
on extra.row_no = c.row_no
and extra.store = c.store
join calc cnext
on cnext.row_no = case when c.value is null
then extra.next_nr
else c.row_no
end
and c.store = cnext.store
join calc cprev
on cprev.row_no = case when c.value is null
then extra.prev_nr
else c.row_no
end
and c.store = cprev.store
我喜歡你的建議,它比我的更優雅。做得好! +1 –
@威廉託德薩爾茲曼:謝謝! :) – Johan
我在想線性插值,你應該找那個。 – Paciv
@podiluska我有.NET中的循環來做到這一點,也是一個Excel模板,將有所有的公式做同樣的事情。因爲,間隔是恆定的,並且它們各自的值將在某些特定的時間間隔內被發現,我總是認爲Excel很容易做到。但是有一個像方法這樣的過程就是我想要的,但如果可能的話,仍然沒有循環。 此外,Excel的問題是每個月都要添加新行時添加公式。 – TiredMaster
@Paciv未知值將被計算但未被估計。另外,我認爲解決方案比插入這種計算開銷要簡單得多。然而,如果你認爲這是尋找的東西,請給我一個領導。謝謝。 – TiredMaster