Sql Server:如何使用别名取消透视?

Posted

技术标签:

【中文标题】Sql Server:如何使用别名取消透视?【英文标题】:Sql Server: How do I unpivot with an alias? 【发布时间】:2013-05-09 15:04:09 【问题描述】:

我知道您可以在带有pivot 的列上使用别名,但我也想使用带有unpivot 的别名。

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

但是,当我执行此操作时出现错误。

我能够实现最终目标的唯一方法是在select 子句中使用case 语句,这并不漂亮。

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

有没有更好的办法?

【问题讨论】:

CASE 声明就是你的做法。您不能在 UNPIVOT 函数中使用别名。 @bluefeet:该死的太快了。我害怕那个。 请注意,Oracle 支持“as”语法,所以这不是一个牵强的需求。 【参考方案1】:

另一种方法是在 unpivot 之前为 起别名,如下所示:

;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

【讨论】:

此方法保留了 unpivot 的效率(与接受的答案相比),同时获得了预期的结果。【参考方案2】:

您不能在 UNPIVOT 函数内分配别名,因此您必须使用 CASE 表达式。

另一种方法是使用 UNION ALL 并立即放置新值:

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 

【讨论】:

这个解决方案的问题是它可能需要多次表扫描。当您开始添加更多列、过滤等时,性能会下降。 Unpivoting 可能在非平凡示例上表现更好。【参考方案3】:

您可以将别名包装在另一个 select 语句中,以便识别别名,然后从那里取消透视:

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

【讨论】:

以上是关于Sql Server:如何使用别名取消透视?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 SQL Server 透视多个列

如何在不使用数据透视和反透视的情况下在 SQL Server 中水平显示数据?

如何远程连接SQL Server数据库

SQL Server:如何在更新语句中使用别名?

sql server 反透视表

在 SQL Server 中如何透视多个列