2017-04-17 154 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

相关问题