我需要合并数据行,例如:
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()的文章。但由于这也涉及到如上所述的选择查询,我认为它的表现要好得多。 (如果我错了,请纠正我。)
请帮忙。感谢。
答案 0 :(得分:0)
尝试使用ROW_NUMBER()
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