1

请帮助我提出想法(最好是 CTE),以尽可能有效地解决这个问题。

在此处输入图像描述

所以...在显示的表格中,“值”列中红色的单元格是已知值,突出显示的绿色是要使用旁边显示的公式计算的值。我试图看看这是否可以通过 CTE 实现。

这就像最后一个已知值及其各自的间隔;下一个已知值和相应的间隔;以及计算该值的时间间隔;all 用于查找值,然后 intern 将以相同的方式用于下一个未知值。

4

2 回答 2

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
于 2012-09-17T07:08:22.170 回答
1

Here is what I came up with (storevalue is the beginning table in your example)

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

Just change the select to an update to write the values into the table.

于 2012-09-15T21:40:39.267 回答