使用unpivot时如何解决列类型的差异?

时间:2013-12-03 11:20:26

标签: sql sql-server tsql pivot unpivot

我在列上使用unpivot时出现问题,这些数据类型并不完全相同,我无法弄清楚如何动态转换列,因为UNPIVOT的语法似乎不支持它。

考虑这个例子:

DECLARE @People TABLE
(PersonId int, Firstname varchar(50), Lastname varchar(50))
-- Load Sample Data
INSERT INTO @People VALUES (1, 'Abe', 'Albertson')
INSERT INTO @People VALUES (2, 'Benny', 'Boomboom')

SELECT PersonId, ColumnName, Value FROM @People
UNPIVOT
(
  ColumnName FOR 
  Value IN (FirstName, LastName)
) 

结果将是:

PersonId    ColumnName        Value
----------- ----------------- ----------------
1           Abe               Firstname
1           Albertson         Lastname
2           Benny             Firstname
2           Boomboom          Lastname

一切都是独角兽和彩虹。现在我将Lastname的数据类型更改为varchar(25),一切都中断了。输出是:

  

列的类型"姓氏"与其他列的类型冲突   在UNPIVOT清单中指定。

我如何解决这个问题并将所有内容转换成动态的varchar(50),而不会篡改桌面上的实际数据类型?

SqlFiddle工作示例(相同数据类型):http://sqlfiddle.com/#!3/f3719

SqlFiddle破解示例(diff数据类型):http://sqlfiddle.com/#!3/5dca13/1

2 个答案:

答案 0 :(得分:5)

您无法在UNPIVOT语法内转换,但您可以转换子查询中的数据,类似于以下内容:

select PersonId, ColumnName, Value  
from
(
  select personid, 
    firstname, 
    cast(lastname as varchar(50)) lastname
  from People
) d
unpivot
(
  Value FOR 
  ColumnName in (FirstName, LastName)
) unpiv;

请参阅SQL Fiddle with Demo

另一种方法是使用CROSS APPLY,根据您的SQL Server版本,您可以使用CROSS APPLY与VALUES或UNION ALL:

select PersonId, ColumnName, Value  
from People
cross apply
(
  select 'firstname', firstname union all
  select 'lastname', cast(lastname as varchar(50))
) c (ColumnName, value)

SQL Fiddle with Demo

答案 1 :(得分:0)

select col1, col2, Answer, Question_Col
from ( 
SELECT 
col1,
col2,
col3,
CAST(col4 AS NVARCHAR(MAX)) col4,

- 注意:此处的数据类型应与先前列

的数据类型相同
CAST(col5 AS NVARCHAR(MAX)) col5
FROM Table_Name )a
unpivot
(
Answer
for Question_Col in (
col3,
col4,
col5
)
) unpiv;