SQL将列数据转换为行并增加列名称

时间:2013-07-30 13:28:16

标签: sql sql-server pivot

我一直在使用SQL一段时间,但我仍然是一个菜鸟,所以我来这里寻求帮助。 我已经在网站上搜索过但是找不到我想要完成的任务。

我想使用SQL来获取如下所示的两列:

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

To This:

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

我正在考虑使用PIVOT,但我不确定如何进行枢轴部分,因为我没有使用Count(),Min(),Max()等。 任何帮助/建议将不胜感激。

2 个答案:

答案 0 :(得分: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

您可以使用PIVOT功能:

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个id,但如果你有一个未知的数字,那么你可以使用动态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) |

答案 1 :(得分: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