2017-10-12 51 views
0

我有一个表,看起来像这样:展开,从现有数据行的SQL

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 

我会怎么走关于这样做?

+2

你正在使用的任何特定的SQL方言?第二个例子是你的数据应该如何存储在第一位,所以我希望你可以这样做,作为修复你的模式的一部分。 – tadman

+1

@tadman - 看到与关键问题完全相反的问题(它必须是大量问题的第一个问题)几乎很有趣,不是吗? – Twelfth

回答

3

您可以使用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 
0

一种方法是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查询)拥有的仅扫描一次表的优势。