我正在寻找一种在SQL Server中将行转换为列的有效方法,听说PIVOT速度不是很快,并且我需要处理很多记录。
这是我的示例:
------------------------------- | Id | Value | ColumnName | ------------------------------- | 1 | John | FirstName | | 2 | 2.4 | Amount | | 3 | ZH1E4A | PostalCode | | 4 | Fork | LastName | | 5 | 857685 | AccountNumber | -------------------------------
这是我的结果:
--------------------------------------------------------------------- | FirstName |Amount| PostalCode | LastName | AccountNumber | --------------------------------------------------------------------- | John | 2.4 | ZH1E4A | Fork | 857685 | ---------------------------------------------------------------------
如何生成结果?
您可以通过多种方式将数据从多行转换为列。
PIVOT
在SQL Server中,您可以使用该PIVOT函数将数据从行转换为列:
select Firstname, Amount, PostalCode, LastName, AccountNumber from ( select value, columnname from yourtable ) d pivot ( max(value) for columnname in (Firstname, Amount, PostalCode, LastName, AccountNumber) ) piv;
参见演示。
columnnames
如果您columnnames要转置的数目未知,则可以使用动态SQL:
DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX) select @cols = STUFF((SELECT ',' + QUOTENAME(ColumnName) from yourtable group by ColumnName, id order by id FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'') set @query = N'SELECT ' + @cols + N' from ( select value, ColumnName from yourtable ) x pivot ( max(value) for ColumnName in (' + @cols + N') ) p ' exec sp_executesql @query;
如果不想使用该PIVOT函数,则可以将聚合函数与CASE表达式一起使用:
CASE
select max(case when columnname = 'FirstName' then value end) Firstname, max(case when columnname = 'Amount' then value end) Amount, max(case when columnname = 'PostalCode' then value end) PostalCode, max(case when columnname = 'LastName' then value end) LastName, max(case when columnname = 'AccountNumber' then value end) AccountNumber from yourtable
也可以使用多个联接来完成此操作,但是您将需要一些列来关联示例数据中没有的每一行。但基本语法为:
select fn.value as FirstName, a.value as Amount, pc.value as PostalCode, ln.value as LastName, an.value as AccountNumber from yourtable fn left join yourtable a on fn.somecol = a.somecol and a.columnname = 'Amount' left join yourtable pc on fn.somecol = pc.somecol and pc.columnname = 'PostalCode' left join yourtable ln on fn.somecol = ln.somecol and ln.columnname = 'LastName' left join yourtable an on fn.somecol = an.somecol and an.columnname = 'AccountNumber' where fn.columnname = 'Firstname'