如何转动桌子?

时间:2016-02-15 08:54:13

标签: sql-server tsql

我有一个动态单行表,如:

PersonId|FirstName|LastName|Address|PhoneNumber
-----------------------------------------------
1        Anuj      Tamrakar  NY     +525418

我想调整此表并希望在临时表中输出如:

PersonalDetails|Value
----------------------
PersonId        1
FirstName       Anuj
LastName        Tamrakar
Address         NY
PhoneNumber     +525418

第一个表是动态单行临时表。对于这个例子,我有5列。根据我的标准,我可能会有更多或更少的列

3 个答案:

答案 0 :(得分:4)

你真的想要UNPIVOT

SELECT  PersonalDetails, Value
FROM 
   (SELECT CAST([PersonId] AS VARCHAR(MAX)) AS [PersonId], 
           CAST([FirstName] AS VARCHAR(MAX))  AS [FirstName],
           CAST([LastName] AS VARCHAR(MAX)) AS [LastName],
           CAST([Address] AS VARCHAR(MAX)) AS [Address],
           CAST([PhoneNumber] AS VARCHAR(MAX)) AS [PhoneNumber]
   FROM mytable) p
UNPIVOT
   (Value FOR PersonalDetails IN 
      ([PersonId], [FirstName], [LastName], [Address], [PhoneNumber])
) AS unpvt;

所有“未被移除”字段必须属于相同类型,因此使用CAST

Demo here

对于动态数量的列,您必须使用动态sql:

DECLARE @cols VARCHAR(MAX) = ''
DECLARE @cast_cols VARCHAR(MAX) = ''
DECLARE @qry VARCHAR(MAX)

SELECT @cols = @cols + ',[' + COLUMN_NAME + ']'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'mytable' AND TABLE_SCHEMA='dbo'

SELECT @cast_cols = @cast_cols + ',CAST([' + COLUMN_NAME + '] AS VARCHAR(MAX)) AS [' + COLUMN_NAME + ']'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'mytable' AND TABLE_SCHEMA='dbo'

SET @cols = STUFF(@cols, 1, 1, '')
SET @cast_cols = STUFF(@cast_cols, 1, 1, '')    

SET @qry = 'SELECT  PersonalDetails, Value FROM (' 
           + @cast_cols +        
          'FROM mytable) p
           UNPIVOT
           (Value FOR PersonalDetails IN (' + @cols + ')
           ) AS unpvt'
EXEC (@qry)

答案 1 :(得分:2)

如果原始表中确实只有一行,那么您可以使用一系列UNION操作来获取输出:

SELECT 'PersonId'    AS PersonalDetails, PersonId AS    Value
FROM yourTable
UNION ALL
SELECT 'FirstName'   AS PersonalDetails, FirstName AS   Value
FROM yourTable
UNION ALL
SELECT 'LastName'    AS PersonalDetails, LastName AS    Value
FROM yourTable
UNION ALL
SELECT 'Address'     AS PersonalDetails, Address AS     Value
FROM yourTable
UNION ALL
SELECT 'PhoneNumber' AS PersonalDetails, PhoneNumber AS Value
FROM yourTable

答案 2 :(得分:0)

SELECT * FROM sys.columns WHERE object_id = OBJECT_ID('dbo.yourTableName') 

这将为您提供列名称。您只需在新表中插入列名称并使用`,insert into temp(PersonalDetails, Value) values(column1,从SingleRowTable中选择column1