How to fill empty cells with previous non empty value or with next empty value if previous not empty value does not exists

Answered How to fill empty cells with previous non empty value or with next empty value if previous not empty value does not exists

  • Wednesday, February 27, 2013 2:03 PM
     
     

    my query returns 

    name person_id value 

    alice    12       

    christa 13  1

    hally    14   

    jack      18   2

    raj        20   

    jane    22    3

    jodie  25

    i need an workaround in order to display 

    alice    12    1    

    christa 13  1

    hally    14   1

    jack      18   2

    raj        20   2

    jane    22    3

    jodie  25   3

    many thanks!!




    • Edited by chopstix21 Wednesday, February 27, 2013 2:04 PM
    • Edited by chopstix21 Wednesday, February 27, 2013 2:05 PM
    • Edited by chopstix21 Wednesday, February 27, 2013 2:21 PM
    •  

All Replies

  • Wednesday, February 27, 2013 2:23 PM
    Moderator
     
     

    If you are using SS 2012 then check the offset functions (LEAD / LAG) in BOL, otherwise you could use a self join approach.

    Edit: LAG and LEAD will not work well if we can have multiple consecutive rows where [value] is the NULL mark.


    AMB

    Some guidelines for posting questions...



  • Wednesday, February 27, 2013 3:32 PM
     
      Has Code

    Try like this,

    declare @Table table (name varchar(10),value int,number varchar(5))
    insert into @Table
    select 'alice', 12,'' union        
    select 'christa',13,'1' union
    select 'hally',14,'' union
    select 'jack', 18,'2' union
    select 'raj',  20,'' union
    select 'jane', 22,'3' union
    select 'jodie',25,'' 
    
    ;with t as(
    select ROW_NUMBER() over(order by value) row,* from @Table
    )
    
    select a.name,b.value,
    case when a.number= '' then b.number
    else a.number
    End Number 
    from t a , t b
    where a.row+1=b.row


    Regards, Dineshkumar
    Please "Mark as Answer" if my post answers your question or "Vote as Helpful" if it helps you

  • Wednesday, February 27, 2013 3:44 PM
    Moderator
     
      Has Code
    create table test2 (name varchar(50), person_id int,value int)
    insert into test2 values ('alice',    12 , null)  ,    
    ('christa', 13,  1),
    ('hally',14,   null),
    ('jack',  18,   2),
    ('raj', 20,   null),
    ('jane',22,    3),
    ('jodie',  25, null)
    
    select * from test2
    
    
    ;with mycte as
    (
    SELECT name,person_id,value, row_number()over(order by person_id ) rn
    FROM test2 A)
    
    SELECT m.name,m.person_id, ISNULL(d.value,e.value) AS value
    FROM   mycte m
           OUTER APPLY (SELECT TOP 1 *  FROM   mycte
                        WHERE  rn <= m.rn AND value IS NOT NULL
                        ORDER  BY rn DESC ) d
           OUTER APPLY (SELECT TOP 1 *  FROM   mycte
                        WHERE  Value IS NOT NULL
                        ORDER  BY rn) e
    ORDER  BY m.person_id 
    

  • Wednesday, February 27, 2013 4:28 PM
    Moderator
     
     Answered Has Code

    Jingyang Li,

    Nice solution!

    If the logic is based on the order of [person_id], then you can avoid ROW_NUMBER.

    WITH R AS (
    SELECT
    	[@T].person_id, [@T].[value], COALESCE(A.val, B.val) AS val
    FROM
    	@T
    	OUTER APPLY
    	(
    	SELECT TOP (1) [value]
    	FROM @T AS T
    	WHERE T.person_id < [@T].person_id AND T.value IS NOT NULL
    	ORDER BY T.person_id DESC
    	) AS A(val)
    	OUTER APPLY
    	(
    	SELECT TOP (1) [value]
    	FROM @T AS T
    	WHERE T.person_id > [@T].person_id AND T.value IS NOT NULL
    	ORDER BY T.person_id
    	) AS B(val)
    WHERE
    	[@T].value IS NULL
    )
    UPDATE R
    SET [value] = val;



    AMB

    Some guidelines for posting questions...