2017-04-17 186 views
0

將以完整代碼再次發佈此問題。最後一次嘗試我沒有寫出全部結果,導致我無法使用的答案。將空值替換爲以前的值 - SQL Server 2008 R2

我有下面的查詢,並希望用該貨幣的以前的值替換最新的空值。有時在同一天有很多空值,有時只有一個。

我想我必須做一些與cteB上的左連接?有任何想法嗎? 見結果和下面使用outer apply()獲得前值的DepositLclCcy,並使用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 
     * 
    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

期望的結果。

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更新了可能表現更好的不同版本。如果您仍然遇到性能問題,請使用[粘貼計劃@ brentozar.com](https://www.brentozar.com/pastetheplan/)分享您的執行計劃,這裏是說明:[如何使用粘貼計劃] (https://www.brentozar.com/pastetheplan/instructions/)。 – SqlZim

相關問題