2

好的,所以我有一些包含大量列的数据,比如 400。

UID, ID, ID, var1, var2, . . . var400

1, 23,  4651,  0,     0, . . .   1
2, 47,  8567,  1,     1, . . .   5

我需要将它堆叠起来,使其看起来像这样:

UID, ID, ID,    Variable,  Value
1,   23, 4651    var1,       0
1,   23, 4651    var2,       0
. . .
1,   23, 4651    var400,     1
2,   47, 8567,   var1        1
2,   47, 8567,   var2        1
. . . 
2,   47, 8567,   var400      5

必须有一些相对简单的方法来执行这种转换。但我想不出它是什么。有人有想法么?

4

2 回答 2

4

好的,这适用于 SQL Server 2005+。你有静态版本UNPIVOT

SELECT UID, ID1, ID2, Variable, Value
FROM (SELECT * FROM YourTable) T
UNPIVOT (Value FOR Variable IN (var1, var2, ....var400)) AS U;

这是一个带有演示的 sqlfiddle 。

这将起作用,但您需要编写 400 列中的每一列。如果您不想这样做(但我建议您这样做),您可以先提取列名并使用动态 SQL:

DECLARE @sql NVARCHAR(MAX), @cols NVARCHAR(MAX)

SELECT @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(COLUMN_NAME) 
                      FROM INFORMATION_SCHEMA.COLUMNS
                      WHERE TABLE_NAME = 'YourTable'
                      AND COLUMN_NAME LIKE 'Var%'
               FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')

SET @sql = '
SELECT UID, ID1, ID2, Variable, Value
FROM (SELECT * FROM YourTable) T
UNPIVOT (Value FOR Variable IN ('+@cols+')) AS U;'

EXEC(@sql)

这是一个动态版本的sqlfiddle。

于 2013-03-20T20:44:24.410 回答
2

如果您使用的是 SQL Server 2008+,那么您可以使用CROSS APPLYwith VALUES

select t.uid,
  t.id1,
  t.id2,
  c.variable,
  c.value
from YourTable t
cross apply
(
  values 
    ('var1', t.var1),
    ('var2', t.var2),
    ('var3', t.var3)
) c (variable, value);

请参阅带有演示的 SQL Fiddle感谢@Lamak 的小提琴

于 2013-03-20T20:54:52.657 回答