从SQL中的现有数据展开行

从SQL中的现有数据展开行,sql,data-manipulation,Sql,Data Manipulation,我有一张这样的桌子: User HasPermA HasPermB HasPermC --------------------------------------- Joe True False True Sally True True True 我需要使用SQL将其转换为以下格式: User PermissionType ----------------------- Joe A Joe

我有一张这样的桌子:

User   HasPermA   HasPermB   HasPermC
---------------------------------------
Joe    True       False      True
Sally  True       True       True
我需要使用SQL将其转换为以下格式:

User   PermissionType
-----------------------
Joe          A
Joe          C
Sally        A
Sally        B
Sally        C
我该怎么做呢?

您可以使用UNION ALL:

select *
from
(
    select user
        , case when HasPermA is true then 'A' else null end as PermissionType
    from table

    union all

    select user
        , case when HasPermB is true then 'B' else null end as PermissionType
    from table

    union all

    select user
        , case when HasPermC is true then 'C' else null end as PermissionType
    from table
) sub
where sub.PermissionType is not null
您可以使用UNION ALL:

select *
from
(
    select user
        , case when HasPermA is true then 'A' else null end as PermissionType
    from table

    union all

    select user
        , case when HasPermB is true then 'B' else null end as PermissionType
    from table

    union all

    select user
        , case when HasPermC is true then 'C' else null end as PermissionType
    from table
) sub
where sub.PermissionType is not null

一种方法是
union all
,我将其表述为:

select user, 'A' as PermissionType from t where HasPermA union all
select user, 'B' from t where HasPermB union all
select user, 'C' from t where HasPermC ;
这假设您的SQL方言理解布尔变量。您可能需要类似于
HasPermA='true'
的内容

SQL的几种方言支持横向联接——使用
lateral
关键字或
apply
关键字(或两者兼用)。如果是,我喜欢:

select t.user, v.PermissionType
from t outer apply
     (value ('A', HasPermA), ('B', HasPermA), ('C', HasPermA)) v(PermissionType, hasPerm)
where hasPerm;

使用横向联接(或
unpivot
query)的优点是只扫描表一次。

一种方法是
union all
,我将其表述为:

select user, 'A' as PermissionType from t where HasPermA union all
select user, 'B' from t where HasPermB union all
select user, 'C' from t where HasPermC ;
这假设您的SQL方言理解布尔变量。您可能需要类似于
HasPermA='true'
的内容

SQL的几种方言支持横向联接——使用
lateral
关键字或
apply
关键字(或两者兼用)。如果是,我喜欢:

select t.user, v.PermissionType
from t outer apply
     (value ('A', HasPermA), ('B', HasPermA), ('C', HasPermA)) v(PermissionType, hasPerm)
where hasPerm;

使用横向联接(或
unpivot
query)的优点是只扫描表一次。

您希望使用哪种特定的SQL方言?第二个例子是数据应该如何存储,所以我希望您可以将此作为修复模式的一部分。@tadman-看到pivot问题(必须是大范围的1问SQL问题)的完全相反几乎很有趣,不是吗?您希望使用哪种特定的SQL方言?第二个例子是数据应该如何存储,所以我希望您可以将此作为修复模式的一部分。@tadman-看到pivot问题(必须是大范围的#1问SQL问题)的完全相反几乎很有趣,不是吗?