あなたはapply
でこれを行うことができます。
select t.dim1, t.dim2, t.dimdate, t2.value
from t outer apply
(select top 1 t2.*
from t t2
where t2.dim1 = t.dim1 and t2.dim2 = t.dim2 and
t2.dimdate <= t.dimdate and t2.value <> 0
order by t2.dimdate desc
) t2;
SQLを使用すると、ウィンドウ関数を使用してやりたい機能を提供しません。 LAG()
にはIGNORE NULLS
オプションがあります。残念ながら、SQL Serverはこのオプションを実装していません。
あなたはウィンドウ関数でこれを行うことができますが、それはもう少し面倒です:
select t.dim1, t.dim2, t.dimdate,
max(value) over (partition by dim1, dim2, effectivedimdate) as value
from (select t.*,
(case when value = 0
then max(case when value <> 0 then dimdate end) over (partition by dim1, dim2 order by dimdate)
else dimdate
end) as effective_dimdate
from t
) t;
max()
スキャンがゼロ以外の値を持つ最新のdimdate
を取得します。この値は、別のmax()
スキャンを使用してすべての値に "拡散"されます。
注:これは、適用する値が常にゼロより大きいと仮定しています。これを処理するコードは簡単に変更できますが、追加のcase
の式はロジックを複雑にします。
これらのいずれかを簡単にアップデートすることができます。第2は特に簡単です:
with toupdate as (
select t.*,
max(value) over (partition by dim1, dim2, effectivedimdate) as new_value
from (select t.*,
(case when value = 0
then max(case when value <> 0 then dimdate end) over (partition by dim1, dim2 order by dimdate)
else dimdate
end) as effective_dimdate
from t
) t
)
update toupdate
set value = newvalue
where value = 0;