2013-07-30 40 views
1

我一直在使用SQL一段时间,但我仍然是一个小菜鸟,所以我来这里寻求帮助。 我在网站上搜索过,但没有完全找到我期望完成的事情。将列数据转换为行并增加列名的SQL

我想用SQL取两列是这样的:

VisitNumber ID 
39332  759666 
39332  769445 
39332  775795 
40329  762595 
40329  769447 
40329  775796 
40329  783782 
39332  783781 
39332  861130 

这样:

VistNumber ID1 ID2 ID3 ID4 ID5 
39332  759666 769445 775795 783781 861130 
40329  762595 769447 775796 783782 NULL 

我想使用PIVOT的,但我不知道究竟如何由于我没有使用Count(),Min(),Max()等等,所以做了数据透视部分。 任何帮助/建议,将不胜感激。

+0

你使用MSSQL服务器? – valex

+0

是的,我正在使用MSSQL服务器。 – Kenry87

+0

你是否需要在单独的列或ID列表中的ID? VisitNumber可以有多于5个ID吗? – BWS

回答

1

由于您使用的是SQL Server,因此您可以通过几种不同的方式获得结果,但所有这些方法都涉及使用row_number()

可以使用聚合函数CASE表达式:

select visitnumber, 
    max(case when seq=1 then id end) ID1, 
    max(case when seq=2 then id end) ID2, 
    max(case when seq=3 then id end) ID3, 
    max(case when seq=4 then id end) ID4, 
    max(case when seq=5 then id end) ID5 
from 
(
    select visitnumber, id, 
    row_number() over(partition by visitnumber 
         order by id) seq 
    from yourtable 
) d 
group by visitnumber; 

SQL Fiddle with Demo

可以使用旋转功能:

select visitnumber, ID1, ID2, ID3, ID4, ID5 
from 
(
    select visitnumber, id, 
    'ID'+cast(row_number() over(partition by visitnumber 
           order by id) as varchar(10)) seq 
    from yourtable 
) d 
pivot 
(
    max(id) 
    for seq in (ID1, ID2, ID3, ID4, ID5) 
) piv; 

SQL Fiddle with Demo。你说,你只会有一个最大的5分的,但如果你有一个未知的数字,那么你可以使用动态SQL得到的结果:

DECLARE @cols AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX) 

select @cols = STUFF((SELECT distinct ',' + QUOTENAME('ID'+cast(row_number() over(partition by visitnumber 
           order by id) as varchar(10))) 
        from yourtable 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT visitnumber,' + @cols + ' 
      from 
      (
       select visitnumber, id, 
        ''ID''+cast(row_number() over(partition by visitnumber 
               order by id) as varchar(10)) seq 
       from yourtable 
      ) x 
      pivot 
      (
       max(id) 
       for seq in (' + @cols + ') 
      ) p ' 

execute sp_executesql @query; 

SQL Fiddle with Demo。所有版本会给结果:

| VISITNUMBER | ID1 | ID2 | ID3 | ID4 | ID5 | 
------------------------------------------------------------ 
|  39332 | 759666 | 769445 | 775795 | 783781 | 861130 | 
|  40329 | 762595 | 769447 | 775796 | 783782 | (null) | 
+0

像枢纽解决方案 –

0
with CTE as 
(

select t.VisitNumber, 
     t.Id, 
     ROW_NUMBER() over (PARTITION BY VisitNumber 
          ORDER BY ID) rn 
from t 
) 

SELECT VisitNumber, 
[1], [2], [3], [4],[5] 
FROM CTE 
PIVOT 
(
AVG(ID) 
FOR RN IN ([1], [2], [3], [4],[5]) 
) AS PivotTable 

SQLFiddle demo

+0

这很好,但我选择了另一个作为答案,但因为如果其他人遇到我的问题将有超过5个ID他们可以使用该答案。 – Kenry87