Sql server 如何将非空数据行合并为一行

Sql server 如何将非空数据行合并为一行,sql-server,tsql,Sql Server,Tsql,我需要合并数据行,例如: pid seq str1 str2 str3 1 1 NULL mary NULL 1 2 jim craig NULL 1 3 kevin NULL NULL 2 1 david NULL NULL 2 2 NULL annie NULL 应成为: pid str1 str2 str3 1 kevi

我需要合并数据行,例如:

pid   seq   str1    str2    str3
1     1     NULL    mary    NULL
1     2     jim     craig   NULL
1     3     kevin   NULL    NULL
2     1    david    NULL    NULL
2     2    NULL     annie   NULL
应成为:

pid str1    str2    str3
1   kevin   craig   NULL
2   david   annie   NULL
下面的工作正常,但速度非常慢,因为所涉及的表大约有1/2百万行,有30列要操作

select pid,                             
(select top 1 p1.str1 from mytable p1 where p1.pid=p2.pid and p1.str1 is not null order by seq desc),
(select top 1 p1.str2 from mytable p1 where p1.pid=p2.pid and p1.str2 is not null order by seq desc),
(select top 1 p1.str3 from mytable p1 where p1.pid=p2.pid and p1.str3 is not null order by seq desc),
...
from mytable p2
group by pid
我在网上看到一些文章建议使用FOR XML PATH()。但由于这也涉及到我上面提到的select查询,我认为它的性能不会更好。(如果我错了,请纠正我。)

请帮忙。谢谢。

尝试使用
行号()

create table temp(
    pid int,
    seq int,
    str1 varchar(50),
    str2 varchar(50),
    str3 varchar(50)
)
insert into temp
select 1, 1, NULL, 'mary', NULL union all 
select 1, 2, 'jim', 'craig', NULL union all 
select 1, 3, 'kevin', NULL, NULL union all 
select 2, 1, 'david', NULL, NULL union all 
select 2, 2, NULL, 'annie', NULL


;with cte as(
    select 
        *,
        rn1 = row_number() over (partition by pid order by case when str1 is not null then seq else 0 end desc),
        rn2 = row_number() over (partition by pid order by case when str2 is not null then seq else 0 end desc),
        rn3 = row_number() over (partition by pid order by case when str3 is not null then seq else 0 end desc)
    from temp
)
select
    pid,
    str1 = max(case when rn1 = 1 then str1 end),
    str2 = max(case when rn2 = 1 then str2 end),
    str3 = max(case when rn3 = 1 then str3 end)
from cte
group by pid

drop table temp