如何在MS SQL 2005中使用条件将水平数据转换为两个单独的垂直表

时间:2013-04-24 16:59:02

标签: sql-server sql-server-2005 unpivot

对于以下问题,我有一种粗暴的解决方案,但我相信这里有人会有一个优雅的解决方案。

我有以下水平导向表。

| Person  | Trait1 | Trait2 |
| Patrick | .3     | .4     |
| James   | .7     | .3     |
| Kristin | .9     | .2     |

理想情况下,我希望根据特征将上述内容分成两个垂直表。会有两个垂直表格,Bad和Terrible。

如果.4< = Trait1< .6 - >坏,Trait1> = .7 - >可怕

如果.3< = Trait2< .5 - >坏,Trait2> = .9 - >可怕

使用这些条件,我们将获得以下表格

BAD
|Person   | Trait  | Value |
| Patrick | Trait2 | .4    | 
| James   | Trait2 | .3    |

Terrible
|Person  | Trait  | Value |
|James   | Trait1 | .7    | 
|Kristin | Trait1 | .9    |

1 个答案:

答案 0 :(得分:3)

由于您使用的是SQL Server 2005,因此可以使用UNPIVOT函数来获取结果。

UNPIVOT获取列并将其转换为行,这将更容易应用您的过滤器。

BAD数据:

select person, trait, value
into bad
from yourtable
unpivot
(
  value
  for trait in (trait1, trait2)
) u
where 
(
  trait ='trait1'
  and value >= .4
  and value < .6
)
or
(
  trait ='trait2'
  and value >= .3
  and value < .5
);

糟糕的数据:

select person, trait, value
into terrible
from yourtable
unpivot
(
  value
  for trait in (trait1, trait2)
) u
where 
(
  trait ='trait1'
  and value >= .7
)
or
(
  trait ='trait2'
  and value >= .9
);

请参阅SQL Fiddle with Demo

注意,这也可以使用UNION ALL查询将UNPIVOT列成行:

select person, trait, value
from
(
  select person, 'trait1' trait, trait1 value
  from yourtable
  union all
  select person, 'trait2' trait, trait2 value
  from yourtable
) d
-- where apply the filter here. 

UNPIVOT和UNION ALL将数据转换为以下格式的垂直格式:

|  PERSON |  TRAIT | VALUE |
----------------------------
| Patrick | trait1 |   0.3 |
|   James | trait1 |   0.7 |
| Kristin | trait1 |   0.9 |