4

如果标题不好,请见谅。但我不知道如何解决这个问题。我一直在为 sql 中的查询而苦苦挣扎。我不知道以前是否有人问过这个问题。但我需要得到第一列不为空。我有一张这样的桌子:

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

我希望输出是这样的:

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

ID列是每行唯一的。

我失败的尝试是创建一个标量函数并为每一列运行它。该函数如下所示:

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

但是这个函数的问题是它只是选择第一列是null. 所以结果是这样的:

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

有什么建议么?

编辑

这将不起作用。

COALESCE(pvt.[0],
pvt.[1],
pvt.[2],
pvt.[3],
pvt.[4],
pvt.[5],
pvt.[6],
pvt.[7],
pvt.[8],
pvt.[9])

因为它会导致相同的输出

4

2 回答 2

3

我会在视图或 CTE 或其他东西中规范化数据,然后运行普通的枢轴。这样,如果您真正规范化表,您将能够重用代码。

-- 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
于 2012-04-12T14:02:36.847 回答
2
select *
from
  (
    select T.ID, C.C, row_number() over(partition by T.ID order by C.N) - 1 as rn
    from @T as T
      cross apply (values (C0, 0),(C1, 1),(C2, 2),(C3, 3),(C4, 4),
                          (C5, 5),(C6, 6),(C7, 7),(C8, 8),(C9, 9)) as C(C, N)
    where C.C is not null
  ) as T
pivot
  (
    min(C) for rn in ([0],[1],[2],[3],[4],[5],[6],[7],[8],[9])
  ) as P

试用SE-Data

于 2012-04-12T14:05:45.390 回答