How to get Previous Value for Null Values

后端 未结 5 925
粉色の甜心
粉色の甜心 2020-12-01 19:02

I have the Below Data in my Table.

   | Id  |  FeeModeId   |Name        |   Amount|
   ---------------------------------------------
   | 1   |  NULL                 


        
相关标签:
5条回答
  • 2020-12-01 19:11

    Please try:

    select 
        a.ID,
        ISNULL(a.FeeModeId, x.FeeModeId) FeeModeId,
        ISNULL(a.Name, x.Name) Name,
        a.Amount
    from tbl a
    outer apply
    (select top 1 FeeModeId, Name 
        from tbl b 
        where b.ID<a.ID and 
            b.Amount is not null and 
            b.FeeModeId is not null and 
            a.FeeModeId is null order by ID desc)x
    

    OR

    select 
        ID,
        ISNULL(FeeModeId, bFeeModeId) FeeModeId,
        ISNULL(Name, bName) Name,
        Amount
    From(
        select 
            a.ID , a.FeeModeId, a.Name, a.Amount, 
            b.ID bID, b.FeeModeId bFeeModeId, b.Name bName,
            MAX(b.FeeModeId) over (partition by a.ID) mx
        from tbl a left join tbl b on b.ID<a.ID
        and b.FeeModeId is not null
    )x 
    where bFeeModeId=mx or mx is null
    
    0 讨论(0)
  • 2020-12-01 19:14

    Since you are on SQL Server 2012... here is a version that uses that. It might be faster than other solutions but you have to test that on your data.

    sum() over() will do a running sum ordered by Id adding 1 when there are a value in the column and keeping the current value for null values. The calculated running sum is then used to partition the result in first_value() over(). The first value ordered by Id for each "group" of rows generated by the running sum has the value you want.

    select T.Id,
           first_value(T.FeeModeId) 
              over(partition by T.NF 
                   order by T.Id 
                   rows between unbounded preceding and current row) as FeeModeId,
           first_value(T.Name)      
              over(partition by T.NS 
                   order by T.Id 
                   rows between unbounded preceding and current row) as Name,
           T.Amount
    from (
         select Id,
                FeeModeId,
                Name,
                Amount,
                sum(case when FeeModeId is null then 0 else 1 end) 
                  over(order by Id) as NF,
                sum(case when Name is null then 0 else 1 end) 
                  over(order by Id) as NS
         from YourTable
         ) as T
    

    SQL Fiddle

    Something that will work pre SQL Server 2012:

    select T1.Id,
           T3.FeeModeId,
           T2.Name,
           T1.Amount
    from YourTable as T1
      outer apply (select top(1) Name
                   from YourTable as T2
                   where T1.Id >= T2.Id and
                         T2.Name is not null
                   order by T2.Id desc) as T2
      outer apply (select top(1) FeeModeId
                   from YourTable as T3
                   where T1.Id >= T3.Id and
                         T3.FeeModeId is not null
                   order by T3.Id desc) as T3
    

    SQL Fiddle

    0 讨论(0)
  • 2020-12-01 19:19
    SELECT
      T.ID,
      ISNULL(T.FeeModeId, 
        (SELECT TOP 1 FeeModeId 
            FROM TableName AS T1 
            WHERE ID < T.ID AND FeeModeId IS NOT NULL 
            ORDER BY ID DESC)) AS FeeModeId,
      ISNULL(Name,
        (SELECT TOP 1 Name 
        FROM TableName 
        WHERE ID < T.ID AND Name IS NOT NULL 
        ORDER BY ID DESC)) AS Name,
      T.Amount
    FROM
      TableName AS T
    
    0 讨论(0)
  • 2020-12-01 19:30
    id  name
    1   toto
    2   NULL
    3   NULL
    4   titi
    5   NULL
    6   NULL
    7   tutu
    8   NULL
    9   NULL
    
    
    SELECT 
           id_table
           ,name
    FROM 
           (
                 SELECT
                        T_01.id AS 'id_table'
                        ,max(T_02.id) AS 'id_name'
                 FROM
                        names AS T_01
                        cross join  
                        (
                              SELECT
                                     id
                                     ,name
                              FROM
                                     names
                              WHERE
                                     name IS NOT NULL
                        ) AS T_02 
                 WHERE 
                        T_02.id <= T_01.id
                 GROUP BY 
                        T_01.id
           ) AS tt02
           left join names
           ON names.id = tt02.id_name
    
    
    id_table    name
    1           toto
    2           toto
    3           toto
    4           titi
    5           titi
    6           titi
    7           tutu
    8           tutu
    9           tutu
    
    0 讨论(0)
  • 2020-12-01 19:35

    try this -

    SELECT Id,
           CASE
             WHEN Feemodeid IS NOT NULL THEN
              Feemodeid
             ELSE
              (SELECT Feemodeid
                 FROM Table_Name t_2
                WHERE t_2.Id = (SELECT MAX(Id)
                                  FROM Table_Name t_3
                                 WHERE t_3.Id < t_1.Id
                                   AND Feemodeid IS NOT NULL))
            END Feemodeid,
           CASE
             WHEN NAME IS NOT NULL THEN
              NAME
             ELSE
              (SELECT NAME
                 FROM Table_Name t_2
                WHERE t_2.Id = (SELECT MAX(Id)
                                  FROM Table_Name t_3
                                 WHERE t_3.Id < t_1.Id
                                   AND NAME IS NOT NULL))
           END NAME,
           Amount
      FROM Table_Name t_1
    
    0 讨论(0)
提交回复
热议问题