2017-04-17 11 views
0

この問題を完全なコードで再度投稿します。最後に試してみましたが、私はそれをすべて書きませんでしたので、私が使用できなかった答えが得られました。null値を以前の値に置き換えます - SQL Server 2008 R2

私は以下のクエリを持っており、最新のNULL値をその通貨の以前の値に置き換えたいとします。同じ日付に多くのnull値が存在することもありますが、時には1つしかないこともあります。

私はcteBの左側の結合で何かする必要があると思いますか?何か案は? 結果を参照してくださいと、クエリ

With cte as (
    SELECT 
     PositionDate, 
     c.Currency, 
     DepositLclCcy 
    FROM 
     [Static].[tbl_DateTable] dt 

    CROSS JOIN (Values ('DKK'), ('EUR'), ('SEK')) as c (Currency) 

    Left join 
    (
    SELECT 
     BalanceDate, 
     Currency, 
     'DepositLclCcy' = Sum(Case when Activity = 'Deposit' then BalanceCcy else 0 END) 
    FROM 
     [Position].[vw_InternalBank] 
    Group By 
     BalanceDate, 
     Currency 
    ) ib 
    on dt.PositionDate = ib.BalanceDate 
     and c.Currency = ib.Currency 
    Where 
     WeekDate = 'Yes') 

    Select 
     * 
    From cte cteA 

    Left join 
    (Select ... from Cte) as cteB 
    on .....  

    Order by 
     cteA.PositionDate desc, 
     cteA.Currency 

現在の結果

PositionDate Currency  DepositLclCcy 
2017-04-11  SEK    1 
2017-04-11  DKK    3 
2017-04-11  EUR    7 
2017-04-10  SEK    NULL 
2017-04-10  DKK    3 
2017-04-10  EUR    5 
2017-04-07  SEK    5 
2017-04-07  DKK    3 
2017-04-07  EUR    5 

望ましい結果

PositionDate Currency  DepositLclCcy 
2017-04-11  SEK    1 
2017-04-11  DKK    3 
2017-04-11  EUR    7 
2017-04-10  SEK    5 
2017-04-10  DKK    3 
2017-04-10  EUR    5 
2017-04-07  SEK    5 
2017-04-07  DKK    3 
2017-04-07  EUR    5 

答えて

1

DepositLclCcyの前の値を取得するためにouter apply()を使用して、そしてcoalesce()を使用してnull値を置き換える以下の望ましい結果。最初の左をスキップ

with cte as (
    select 
     PositionDate 
    , c.Currency 
    , DepositLclCcy 
    from [Static].[tbl_DateTable] dt 
    cross join (values ('DKK') , ('EUR') , ('SEK')) as c(Currency) 
    left join (
     select 
      BalanceDate 
     , Currency 
     , DepositLclCcy = Sum(case when Activity = 'Deposit' then BalanceCcy else 0 end) 
     from [Position].[vw_InternalBank] 
     group by BalanceDate, Currency 
    ) ib 
     on dt.PositionDate = ib.BalanceDate 
     and c.Currency = ib.Currency 
    where WeekDate = 'Yes' 
) 
select 
    cte.PositionDate 
    , cte.Currency 
    , DepositLclCcy = coalesce(cte.DepositLclCcy,x.DepositLclCcy) 
from cte 
    outer apply (
    select top 1 i.DepositLclCcy 
    from cte as i 
    where i.PositionDate < cte.PositionDate 
     and i.Currency = cte.Currency 
    order by i.PositionDate desc 
    ) as x 

代わりに参加し、そこouter apply()を使用して:

with cte as (
    select 
     dt.PositionDate 
    , c.Currency 
    , ib.DepositLclCcy 
    from [Static].[tbl_DateTable] dt 
    cross join (values ('DKK'), ('EUR'), ('SEK')) as c(Currency) 
    outer apply (
     select top 1 
      DepositLclCcy = sum(BalanceCcy) 
     from [Position].[vw_InternalBank] as i 
     where i.Activity = 'Deposit' 
     and i.Currency = c.Currency 
     and i.BalanceDate <= dt.PositionDate 
     group by i.BalanceDate, i.Currency 
     order by i.BalanceDate desc 
    ) as ib 
    where dt.WeekDate = 'Yes' 
) 
select * 
from cte 
+0

感謝を!私は "CTE"データをテンポラリテーブルに送り、外部適用クエリを使用すると完璧に動作します。 しかし、CTEを指すとき、クエリは非常に遅く、ちょうど回り回っているようです。クエリ時間は決して終わりません。 クエリ/ビュー/テーブルで変更/チェック/実行できるものはありますか? – Haggan

+0

@Hagganより優れたパフォーマンスを示す別のバージョンで更新されました。それでもパフォーマンスに問題がある場合は、[Plan @ brentozar.com](https://www.brentozar.com/pastetheplan/)を使用して実行計画を共有してください。[計画の貼り付け方法] (https://www.brentozar.com/pastetheplan/instructions/)。 – SqlZim

関連する問題