如何将多行数据转换为具有唯一ID的字符串?

时间:2013-07-25 15:02:51

标签: sql-server-2008 transpose

我有一个包含数百万行的文件需要转换。我无法获得理想的结果,所以我想顺从专家;

select
[ID],
min ([date]) as 'Payment1',
min ([date]) as 'Payment2', 
where 'Payment2' > 'Payment1'
min ([date]) as 'Payment3', 
where 'Payment3' > 'Payment2'
min ([date]) as 'Payment4', 
where 'Payment4' > 'Payment3'
from [FP&A].[dbo].[PaymentSchedules]
group by [ID]
order by [ID]

2 个答案:

答案 0 :(得分:0)

您似乎希望选择四个最低的不同日期作为您的四次付款。我将提出一个易于理解的方法来获得这个:

  1. 查找payment1
  2. 再次加入该表以查找payment2
  3. 再次加入该表以查找payment3
  4. ...
  5. 最终结果如下:

    with step1 as (
      select id, min(date) as payment1
      from ps
      group by id
    ), step2 as (
      select step1.*, min(date) as payment2
      from step1
      join ps on step1.id = ps.id
      where step1.payment1 < ps.date
      group by step1.id, payment1
    ), step3 as (
      select step2.*, min(date) as payment3
      from step2
      join ps on step2.id = ps.id
      where step2.payment2 < ps.date
      group by step2.id, payment1, payment2
    ), step4 as (
      select step3.*, min(date) as payment4
      from step3
      join ps on step3.id = ps.id
      where step3.payment3 < ps.date
      group by step3.id, payment1, payment2, payment3
    )
    select * from step4
    

    这是一个小提琴,展示了它的实际效果:http://sqlfiddle.com/#!3/66576/8

    现在这会产生4个连接,所以性能不是最好的。如果您遇到性能问题,那么我会考虑对日期进行排名,选择四个最低值(不包括重复项),然后转动表格。

答案 1 :(得分:0)

所以朋友的朋友知道我在做什么,并想出了这个代码,分两步完成了这个过程。我发布它以防将来帮助其他人;

Select [DBO].[ID], 
[DBO].[Date], 
count(*) as 'alias1'
into ##Temp
from [DBO] left outer join [DBO] as 'alias2'
on [DBO].[ID] = [alias2].[id]
And [DBO].[Date] >= [alias2].[Date]
Group BY [dbo].[id], 
     [dbo].[Date]
order by [dbo].[ID], [dbo].[alias1]


Select ##Temp.id, 
MIN(case when [alias1] = 1 then Date Else NULL END) as Payment1,
MIN(case when [alias1] = 2 then Date Else NULL END) as Payment2,
MIN(case when [alias1] = 3 then Date Else NULL END) as Payment3,
MIN(case when [alias1] = 4 then Date Else NULL END) as Payment4,
MIN(case when [alias1] = 5 then Date Else NULL END) as Payment5,
MIN(case when [alias1] = 6 then Date Else NULL END) as Payment6,
MIN(case when [alias1] = 7 then Date Else NULL END) as Payment7,
MIN(case when [alias1] = 8 then Date Else NULL END) as Payment8,
MIN(case when [alias1] = 9 then Date Else NULL END) as Payment9
from ##
group by ##Temp.id
order by ##Temp.id