将null值替换为以前的值 - SQL Server 2008 R2

时间:2017-04-17 10:03:29

标签: replace null sql-server-2008-r2

将使用完整代码再次发布此问题。最后一次尝试我没有写出所有导致我无法使用的答案。

我有以下查询,并希望将最新的NULL值替换为该货币的先前值。有时在同一天有很多空值,有时只有一个。

我想我必须在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 个答案:

答案 0 :(得分:1)

使用outer apply()获取DepositLclCcy的上一个值,并使用null替换coalesce()值。

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