1

請幫助我提出想法(最好是CTE)以儘可能高效地解決此問題。使用CTE或任何有效的遞歸填充計算

enter image description here

因此...在示出的表中,在列「值」的細胞,其是紅是已知值0​​和突出顯示的果嶺與所示旁邊的公式計算的值。 我正在嘗試查看CTE是否可能。

這就像最後一次已知的值及其相應的間隔;下一個已知的值和相應的間隔;以及計算值的間隔;所有這些都是用來找到那個實習生將以同樣的方式用於下一個未知值的值。

+0

我在想線性插值,你應該找那個。 – Paciv

+0

@podiluska我有.NET中的循環來做到這一點,也是一個Excel模板,將有所有的公式做同樣的事情。因爲,間隔是恆定的,並且它們各自的值將在某些特定的時間間隔內被發現,我總是認爲Excel很容易做到。但是有一個像方法這樣的過程就是我想要的,但如果可能的話,仍然沒有循環。 此外,Excel的問題是每個月都要添加新行時添加公式。 – TiredMaster

+0

@Paciv未知值將被計算但未被估計。另外,我認爲解決方案比插入這種計算開銷要簡單得多。然而,如果你認爲這是尋找的東西,請給我一個領導。謝謝。 – TiredMaster

回答

1

這裏是我想出了(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 

就改變選擇到一個更新的值寫入到表中。

2

這是一個解決方案。

希望它有幫助。 :)

;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 
+0

我喜歡你的建議,它比我的更優雅。做得好! +1 –

+0

@威廉託德薩爾茲曼:謝謝! :) – Johan