我怎样才能将表格两​​次取消?

时间:2014-12-09 10:32:12

标签: sql sql-server unpivot

我需要帮助解开表格。我有一个像这样的类似结构的表(UserRoles可以为空,实际上日期不会被填充)

Object  User_RoleX  User_RoleY User_RoleZ RoleX_Date RoleY_Date
======  =========== ========== ========== ========== ==========
O1      User 1      User 2     User 3     2014-12-08 2013-12-09
O2      NULL        User 1     User 2     NULL       2013-12-09
O3      User 1      NULL       User 1     2014-12-08 NULL

我使用以下命令将此表格取消:

unpivot(Username for Role in ([User_RoleX], [User_RoleY], [User_RoleZ])) as result

得到以下结果:(我明白了,因为Datecolumns稍后来到这个表,并且unpivot命令不是为这些日期列设计的)

Object  Username   Role        RoleX_Date  RoleY_Date
======  ========== ==========  ==========  ============
O1      User1      X           2014-12-08  2013-12-09
O1      User2      Y           2014-12-08  2013-12-09
O1      User3      Z           2014-12-08  2013-12-09

O2      User1      Y           NULL        2013-12-09
O2      User2      Z           NULL        2013-12-09

O3      User1      X           2014-12-08  NULL
O3      User1      Z           2014-12-08  NULL

我想要的结果如下,但我没有用unpivot命令得到这个(角色Z没有约会)

Object  Username   Role        Date 
======  ========== ==========  ========== 
O1      User1      X           2014-12-08 
O1      User2      Y           2013-12-09 
O1      User3      Z           (NullOrEmpty)

O2      User1      Y           2013-12-09      
O2      User2      Z           (NullOrEmpty)        

O3      User1      X           2014-12-08  
O3      User1      Z           (NullOrEmpty) 

当我在unpivot语句中插入2个日期列时,我收到一条错误消息,其中说明日期列与其他列的类型冲突,这些列在unpivot列表中声明

也许有人可以给我一个提示,如何为这个预期的情况编辑unpivot命令。

3 个答案:

答案 0 :(得分:2)

我实际上建议使用CROSS APPLY将多个列一起展开。从SQL Server 2005开始,可以使用CROSS APPLY和UNION ALL或VALUES。

使用UNION ALL

,逻辑类似于以下内容
select 
  t.object, 
  c.Username,
  c.Role,
  c.Date
from yourtable t  -- or query
cross apply
(
  select 'X', User_RoleX, RoleX_Date union all
  select 'Y', User_RoleY, RoleY_Date union all
  select 'Z', User_RoleZ, null
) c (Role, UserName, Date);

SQL Fiddle with Demo。如果需要其他过滤,则可以包含WHERE子句。

如果您想使用VALUES子句,那么您将使用:

select 
  t.object, 
  c.Username,
  c.Role,
  c.Date
from yourtable t
cross apply
(
  values
    ('X', User_RoleX, RoleX_Date),
    ('Y', User_RoleY, RoleY_Date),
    ('Z', User_RoleZ, null)
) c (Role, UserName, Date);

SQL Fiddle with Demo。两者都给出了类似的结果:

| OBJECT | USERNAME | ROLE |                            DATE |
|--------|----------|------|---------------------------------|
|     O1 |   User 1 |    X | December, 08 2014 00:00:00+0000 |
|     O1 |   User 2 |    Y | December, 09 2013 00:00:00+0000 |
|     O1 |   User 3 |    Z |                          (null) |
|     O2 |   (null) |    X |                          (null) |

答案 1 :(得分:1)

您可以将现有结果用作CTE,然后使用union ..

With X as 
(
  -- current statement
)
Select Object, UserName, Role, RoleX_Date as Date
From X
Union All
Select Object, UserName, Role, RoleY_Date as Date
From X

结果将不是你所期望的那样。但我并没有真正得到结果的逻辑。这可能会提供一些想法..

答案 2 :(得分:0)

如果你想解锁(或转动)两次甚至多次,最简单的方法是将你要拆分的列连接到两者之间的分隔符:

Select Column1, Column2 + '|' + Column3 From Table

在结果中,您可以轻松拆分连接列...