通过测试对结果进行分组

时间:2014-01-28 14:31:10

标签: sql-server pivot

我有一个具有这种结构的表:

Test    Value   Shape

1       1,89    20
1       2,08    27
1       2,05    12
2       2,01    12
2       2,05    35
2       2,03    24

我需要为每个Test值提供一个列,在这种情况下,如下所示:

 Test 1         | Test 2

Value | Shape   | Value | Shape

我尝试用pivot做这个,但结果并不好。有人能帮助我吗?

[]的

1 个答案:

答案 0 :(得分:2)

由于您使用的是SQL Server,因此可以通过几种不同的方式获得结果。为了获得结果,您首先需要创建一个唯一值,以便为每个Test返回多行。我会应用像row_number()这样的窗口函数:

select test, value, shape,
  row_number() over(partition by test
                    order by value) seq
from yourtable

此查询将用作进程其余部分的基础。这为每个test创建了一个唯一的序列,然后当您应用聚合函数时,您可以返回多行。

您可以使用带有CASE表达式的聚合函数来获取最终结果:

select 
  max(case when test = 1 then value end) test1Value,
  max(case when test = 1 then shape end) test1Shape,
  max(case when test = 2 then value end) test2Value,
  max(case when test = 2 then shape end) test2Shape
from
(
  select test, value, shape,
    row_number() over(partition by test
                      order by value) seq
  from yourtable
) d
group by seq;

SQL Fiddle with Demo

如果你想实现PIVOT功能,那么我首先需要取消ValueShape的多个列,然后应用PIVOT。您仍将使用row_number()生成返回多行所需的唯一序列。基本语法为:

;with cte as
(
  -- get unique sequence
  select test, value, shape,
    row_number() over(partition by test
                      order by value) seq
  from yourtable
) 
select test1Value, test1Shape,
  test2Value, test2Shape
from
(
  -- unpivot the multiple columns
  select t.seq,
    col = 'test'+cast(test as varchar(10))
          + col,
    val
  from cte t
  cross apply
  (
    select 'value', value union all
    select 'shape', cast(shape as varchar(10))
  ) c (col, val)
) d
pivot
(
  max(val)
  for col in (test1Value, test1Shape,
              test2Value, test2Shape)
) piv;

SQL Fiddle with Demo。两个版本都给出了结果:

| TEST1VALUE | TEST1SHAPE | TEST2VALUE | TEST2SHAPE |
|------------|------------|------------|------------|
|       1,89 |         20 |       2,01 |         12 |
|       2,05 |         12 |       2,03 |         24 |
|       2,08 |         27 |       2,05 |         35 |