How to get the first column that is not null

null, sql-server-2005, sql-server-2008-r2, t-sql

Solution

I would normalize the data in a view or CTE or something, then run an ordinary pivot. This way, should you ever actually normalize the table, you'll be able to reuse code.

-- Setup test data
declare @texts table (
      ID int not null primary key
    , Col0 varchar(10) null
    , Col1 varchar(10) null
    , Col2 varchar(10) null
    , Col3 varchar(10) null
    , Col4 varchar(10) null
    , Col5 varchar(10) null
    , Col6 varchar(10) null
    , Col7 varchar(10) null
    , Col8 varchar(10) null
    , Col9 varchar(10) null
)
insert into @texts select 59, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'text1'
insert into @texts select 185, NULL, NULL, NULL, NULL, NULL, 'text1', 'text2', 'text3', 'text4', 'text5'
insert into @texts select 428, NULL, NULL, NULL, NULL, NULL, NULL, 'text1', 'text2', 'text3', 'text4'
insert into @texts select 53, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'text1', 'text2'
insert into @texts select 452, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'text1'
insert into @texts select 267, 'text1', 'text2', 'text3', 'text4', 'text5', 'text6', 'text7', 'text8', 'text9', 'text10'

-- Normalize and get new column in a CTE
;with cte as (
    select *
        , row_number() over (partition by ID order by Col) - 1 as NewCol
    from (
        select ID, 0 as Col
            , (select Col0 from @texts where ID = a.ID) as Val
        from @texts a
        union all
        select ID, 1 as Col
            , (select Col1 from @texts where ID = a.ID) as Val
        from @texts a
        union all
        select ID, 2 as Col
            , (select Col2 from @texts where ID = a.ID) as Val
        from @texts a
        union all
        select ID, 3 as Col
            , (select Col3 from @texts where ID = a.ID) as Val
        from @texts a
        union all
        select ID, 4 as Col
            , (select Col4 from @texts where ID = a.ID) as Val
        from @texts a
        union all
        select ID, 5 as Col
            , (select Col5 from @texts where ID = a.ID) as Val
        from @texts a
        union all
        select ID, 6 as Col
            , (select Col6 from @texts where ID = a.ID) as Val
        from @texts a
        union all
        select ID, 7 as Col
            , (select Col7 from @texts where ID = a.ID) as Val
        from @texts a
        union all
        select ID, 8 as Col
            , (select Col8 from @texts where ID = a.ID) as Val
        from @texts a
        union all
        select ID, 9 as Col
            , (select Col9 from @texts where ID = a.ID) as Val
        from @texts a
    ) as b
    where b.Val is not null
)
-- Run a pivot of the CTE
select ID
    , (select Val from cte where ID = a.ID and NewCol = 0) as Col0
    , (select Val from cte where ID = a.ID and NewCol = 1) as Col1
    , (select Val from cte where ID = a.ID and NewCol = 2) as Col2
    , (select Val from cte where ID = a.ID and NewCol = 3) as Col3
    , (select Val from cte where ID = a.ID and NewCol = 4) as Col4
    , (select Val from cte where ID = a.ID and NewCol = 5) as Col5
    , (select Val from cte where ID = a.ID and NewCol = 6) as Col6
    , (select Val from cte where ID = a.ID and NewCol = 7) as Col7
    , (select Val from cte where ID = a.ID and NewCol = 8) as Col8
    , (select Val from cte where ID = a.ID and NewCol = 9) as Col9
from cte a
group by ID
order by ID

Problem

Sorry if the title is bad. But I do not know how to address the problem. I've been really struggling with a query in sql. I do not know if this question has been asked before. But I need to get the first column that is not null. I have a table like this: ``` ID 0 1 2 3 4 5 6 7 8 9 59 NULL NULL NULL NULL NULL NULL NULL NULL NULL text1 185 NULL NULL NULL NULL NULL text1 text2 text3 text4 text5 428 NULL NULL NULL NULL NULL NULL text1 text2 text3 text4 53 NULL NULL NULL NULL NULL NULL NULL NULL text1 text2 452 NULL NULL NULL NULL NULL NULL NULL NULL NULL text1 267 text1 text2 text3 text4 text5 text6 text7 text8 text9 text10 ``` And I would like the output to be like this: ``` ID 0 1 2 3 4 5 6 7 8 9 59 text1 NULL NULL NULL NULL NULL NULL NULL NULL NULL 185 text1 text2 text3 text4 text5 NULL NULL NULL NULL NULL 428 text1 text2 text3 text4 NULL NULL NULL NULL NULL NULL 53 text1 text2 NULL NULL NULL NULL NULL NULL NULL NULL 452 text1 NULL NULL NULL NULL NULL NULL NULL NULL NULL 267 text1 text2 text3 text4 text5 text6 text7 text8 text9 text10 ``` The `ID` column is unique per row. My failed attempt was to create a scalared function and run it for each column. The function looks like this: ``` CREATE FUNCTION GetCulumnsThatIsNotNull ( @column1 VARCHAR(500), @column2 VARCHAR(500), @column3 VARCHAR(500), @column4 VARCHAR(500), @column5 VARCHAR(500), @column6 VARCHAR(500), @column7 VARCHAR(500), @column8 VARCHAR(500), @column9 VARCHAR(500), @column10 VARCHAR(500) ) RETURNS VARCHAR(500) AS BEGIN RETURN COALESCE(@column1, COALESCE(@column2, COALESCE(@column3, COALESCE(@column4, COALESCE(@column5, COALESCE(@column6, COALESCE(@column8, COALESCE(@column9, COALESCE(@column10,null))))))))) END ``` But the problem with this function is that it is just picking the first column that are `null`. So the result get like this: ``` ID 0 1 2 3 4 5 6 7 8 9 59 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 185 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 428 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 53 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 452 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 267 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 ``` Any suggestions? EDIT This will not work ether. ``` COALESCE(pvt.[0], pvt.[1], pvt.[2], pvt.[3], pvt.[4], pvt.[5], pvt.[6], pvt.[7], pvt.[8], pvt.[9]) ``` Because it will result in the same output

Original source