4

I know that you can use an alias on a column with pivot, but I'd like to use an alias with unpivot as well.

select UserId
,      ContactMethod
,      ContactMethodValue
from Users
unpivot (
    ContactMethodValue for ContactMethod in
    (   HomePhone      as [3000]
    ,   OfficePhone    as [3001]
    ,   CellPhone      as [3002]
    ,   Fax            as [3003]
    ,   Website        as [3005]
    )
 ) as unpvt

However I get an error when I do this.

The only way I've been able to accomplish my end goal is to use a case statement in the select clause, which isn't pretty.

select UserId
,      ( case ContactMethod
         when 'HomePhone'    then 3000
         when 'OfficePhone'  then 3001
         when 'CellPhone'    then 3002
         when 'Fax'          then 3003
         when 'Website'      then 3005
         end ) as ContactMethod
,      ContactMethodValue
from Users
unpivot (
    ContactMethodValue for ContactMethod in
    (   HomePhone
    ,   OfficePhone
    ,   CellPhone
    ,   Fax
    ,   Website
    )
 ) as unpvt

Is there a better way?

Master Morality
  • 5,837
  • 6
  • 31
  • 43

3 Answers3

4

Another method is to alias before the unpivot, as with:

;with aliasedUsers as (
    select
        UserId,
        HomePhone      as [3000]
        OfficePhone    as [3001]
        CellPhone      as [3002]
        Fax            as [3003]
        Website        as [3005]
)
select UserId
,      ContactMethod
,      ContactMethodValue
from aliasedUsers
unpivot (
    ContactMethodValue for ContactMethod in
    (   [3000]
    ,   [3001]
    ,   [3002]
    ,   [3003]
    ,   [3005]
    )
) as unpvt
Jeff
  • 12,555
  • 5
  • 33
  • 60
  • This method preserves the efficiency of the unpivot (compared with the accepted answer), while getting the desired outcome. – Stobor Sep 22 '20 at 01:45
2

You cannot assign an alias inside of the UNPIVOT function so you would have to use the CASE expression.

Another way would be to use a UNION ALL and just place the new values immediately:

select userid, 3000 as ContactMethod, homePhone as ContactMethodValue
from users 
union all
select userid, 3001 as ContactMethod, OfficePhone as ContactMethodValue
from users 
union all
select userid, 3002 as ContactMethod, CellPhone as ContactMethodValue
from users 
union all
select userid, 3003 as ContactMethod, Website as ContactMethodValue
from users 
union all
select userid, 3005 as ContactMethod, homePhone as ContactMethodValue
from users 
Taryn
  • 242,637
  • 56
  • 362
  • 405
  • The problem with this solution is it potentially requires multiple table scans. As you start to add more columns, filtering, etc. performance degrades. Unpivoting is likely to perform better on non-trivial examples. – Necreaux Jun 27 '18 at 17:28
0

You can wrap the aliases in another select statement so the aliases are recognized, and unpivot it from there:

select * from
        (select UserId,
            HomePhone      as [3000]
            OfficePhone    as [3001]
            CellPhone      as [3002]
            Fax            as [3003]
            Website        as [3005]
        from aliasedUsers) P
        unpivot (ContactMethodValue for ContactMethod in ([3000],[3001],[3002],[3003],[3005])) as unpvt
Joey
  • 41
  • 2