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

これが私が思いついたものです(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

選択を更新に変更するだけで、値がテーブルに書き込まれます。

于 2012-09-15T21:40:39.267 に答える