在Sql Server中将行转换为多行中的列

时间:2016-06-16 06:48:50

标签: sql sql-server

我有一张这样的表

CREATE table #yourtable
([Id] int, [Value] varchar(16), [ColumnName] varchar(13), [RecId] varchar(5));

INSERT INTO #yourtable
([Id], [Value], [ColumnName], [RecId])
VALUES
(1, 'John', 'FirstName', '1'),
(2, '2.4', 'Amount', '1'),
(3, 'ZH1E4A', 'PostalCode', '1'),
(4, 'Fork', 'LastName', '1'),
(5, '857685', 'AccountNumber', '1'),
(6, 'Bill', 'FirstName', '2'),
(7, '4.2', 'Amount', '2'),
(8, '48122', 'PostalCode', '2'),
(9, 'White', 'LastName', '2'),
(10, '129845', 'AccountNumber', '2');

我需要有两行像这样

enter image description here

我们需要一个有效的模式,因为我有很多行。谢谢你的帮助。

2 个答案:

答案 0 :(得分:1)

您可以使用PIVOT

SELECT [FirstName], [Amount], [PostalCode], 
       [LastName], [AccountNumber]
FROM (
   SELECT RecId, Value, ColumnName
   FROM #yourtable) AS src
PIVOT (
   MAX(Value) FOR ColumnName IN ([FirstName], [Amount], [PostalCode], 
                                 [LastName], [AccountNumber])) AS pvt

答案 1 :(得分:1)

另一种方法是使用交叉表或条件聚合:

SELECT  
      MAX(CASE WHEN ColumnName = 'FirstName' THEN Value END) AS [FirstName]
    , MAX(CASE WHEN ColumnName = 'Amount' THEN Value END) AS [Amount]
    , MAX(CASE WHEN ColumnName = 'PostalCode' THEN Value END) AS [PostalCode]
    , MAX(CASE WHEN ColumnName = 'LastName' THEN Value END) AS [LastName]
    , MAX(CASE WHEN ColumnName = 'AccountNumber' THEN Value END) AS [AccountNumber]
FROM #yourtable
GROUP BY RecId;

但是,如果您的ColumnName数量未知,则应动态执行:

DECLARE @sql NVARCHAR(MAX);

SELECT @sql =
'SELECT ' + CHAR(10) +
(SELECT STUFF((SELECT
'   , MAX(CASE WHEN ColumnName = ''' + ColumnName + ''' THEN Value END) AS ' + QUOTENAME(ColumnName) + CHAR(10)
FROM #yourtable
GROUP BY ColumnName
ORDER BY MIN(Id)
FOR XML PATH('')
), 1, 2, '')) +
'FROM #yourtable
GROUP BY RecId;';

PRINT (@sql);
EXEC (@sql);

ONLINE DEMO

参考: