需要将行转换为具有排序的列

时间:2013-10-23 23:22:13

标签: sql-server sql-server-2008 tsql

我正在尝试将行转换为列,但包含一些数据。

示例数据 例如:

+-----+------+------+
| CId | Cat1 | cat2 |
+-----+------+------+
|   1 |   10 |    6 |
|   1 |  230 |  100 |
|   2 | 1222 |   30 |
|   3 |    2 |   50 |
|   4 |   33 |   21 |
|   1 |   33 |   13 |
+-----+------+------+

预期输出

+-----+------+-----+-----+-----+-----+-----+
| CId | Rw1  | Rw2 | Rw3 | Rw4 | Rw5 | Rw6 |
+-----+------+-----+-----+-----+-----+-----+
|   1 |   10 |  33 | 230 |   6 |  13 | 100 |
|   2 | 1222 |  30 |   0 |   0 |   0 |   0 |
|   3 |    2 |  50 |   0 |   0 |   0 |   0 |
|   4 |   33 |  21 |   0 |   0 |   0 |   0 |
+-----+------+-----+-----+-----+-----+-----+

在完成后CID: 1了解Cat1cat2的所有值的排序方式,需要对{{1}}进行排序,所有内容都应该在一行中。

请让我知道怎么做。

1 个答案:

答案 0 :(得分:3)

您可以通过取消隐藏和旋转数据来获得结果,但您还需要使用row_number()将数据保存在所需的序列中。

第一步是查询您当前的数据并应用row_number()获取每行的值,按cid分区并按cat1cat2排序:

select cid, cat1, cat2,
  row_number() over(partition by cid order by cat1, cat2) seq
from yourtable

Demo。获得数据后,您将多列cat1cat2取消汇总到包含多行的单个列中。您可以使用UNPIVOT功能,也可以使用CROSS APPLY转换数据:

select cid, value
  , 'rw'+cast(row_number() over(partition by cid order by col, seq) as varchar(10)) rw
from 
(
  select cid, cat1, cat2,
    row_number() over(partition by cid order by cat1, cat2) seq
  from yourtable
) d
cross apply
(
  select 1, cat1 union all
  select 2, cat2
) c (col, value)

Demo。当您取消数据转换时,您将再次应用row_number(),这将用于创建新的列名称。这次应用时,您将按cid对数据进行分区,然后按列cat1 / cat2(我使用1 / 2)进行排序以及您原始创建的序列。这个新的行号将创建所有新的列标题,它将按照您希望显示的顺序保存数据。

最后,您将应用PIVOT功能:

select cid,
  coalesce(rw1, 0) rw1, 
  coalesce(rw2, 0) rw2, 
  coalesce(rw3, 0) rw3, 
  coalesce(rw4, 0) rw4, 
  coalesce(rw5, 0) rw5, 
  coalesce(rw6, 0) rw6
from 
(
  select cid, value
    , 'rw'+cast(row_number() over(partition by cid order by col, seq) as varchar(10)) rw
  from 
  (
    select cid, cat1, cat2,
      row_number() over(partition by cid order by cat1, cat2) seq
    from yourtable
  ) d
  cross apply
  (
    select 1, cat1 union all
    select 2, cat2
  ) c (col, value)
) src
pivot
(
  max(value)
  for rw in (rw1, rw2, rw3, rw4, rw5, rw6)
) piv;

SQL Fiddle with Demo。这给出了最终结果:

| CID |  RW1 | RW2 | RW3 | RW4 | RW5 | RW6 |
|-----|------|-----|-----|-----|-----|-----|
|   1 |   10 |  33 | 230 |   6 |  13 | 100 |
|   2 | 1222 |  30 |   0 |   0 |   0 |   0 |
|   3 |    2 |  50 |   0 |   0 |   0 |   0 |
|   4 |   33 |  21 |   0 |   0 |   0 |   0 |