Question

I am having problems using unpivot on columns, that are not the exact same datatype, and I can't figure out how to convert the columns on the fly, because the syntax for UNPIVOT does not seem to support it.

Consider this example:

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)
) 

The result would be this:

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

Everything is unicorns and rainbows. Now I change the datatype of Lastname to varchar(25) and everything breaks. The output is:

The type of column "Lastname" conflicts with the type of other columns specified in the UNPIVOT list.

How can I get around this and convert everything to say a varchar(50) on the fly, without tampering with the actual data types on the table?

SqlFiddle working example (same datatype): http://sqlfiddle.com/#!3/f3719

SqlFiddle broken example (diff datatypes): http://sqlfiddle.com/#!3/5dca13/1

Was it helpful?

Solution

You cannot convert inside the UNPIVOT syntax but you can convert the data inside a subquery similar to the following:

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;

See SQL Fiddle with Demo

Another way to do this would be to use CROSS APPLY, depending on your version of SQL Server you can use CROSS APPLY with VALUES or 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)

See SQL Fiddle with Demo.

OTHER TIPS

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

-- Note: Here datatype should be same as that of previous columns

CAST(col5 AS NVARCHAR(MAX)) col5
FROM Table_Name )a
unpivot
(
Answer
for Question_Col in (
col3,
col4,
col5
)
) unpiv;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top