我正在寻找一种在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'