在SQL Server中将列转换为行和列名称

时间:2017-04-06 12:52:24

标签: sql sql-server sql-server-2008 sql-server-2012 sql-server-2008-r2

我想将列转换为SQL Server中的行:

Id   Value  Jan1  Jan2
----------------------
1     2      25    35
2     5      45    45

结果应该是

Id  Value Month 1  2
----------------------
1    2     Jan  25 35
2    5     Jan  45 45

我怎样才能得到这个结果?有人请帮忙

3 个答案:

答案 0 :(得分:1)

这似乎是:

select Id, Value, 'Jan' as [month], Jan1 as [1], Jan2 as [2]
from t;

您基本上只是在输出中添加另一列。

我不建议使用数字作为列名,也不建议使用month等SQL Server关键字。

答案 1 :(得分:1)

你在问什么似乎有点奇怪。如果我将您的示例扩展为包含Feb1Feb2的列,那么我会看到两个用于转置列的选项:

+----+-------+------+------+------+------+
| Id | Value | Jan1 | Jan2 | Feb1 | feb2 |
+----+-------+------+------+------+------+
|  1 |     2 |   25 |   35 |   15 |   28 |
|  2 |     5 |   45 |   45 |   60 |   60 |
+----+-------+------+------+------+------+

转移月份部分:

select Id, Value, MonthName, MonthValue1, MonthValue2
from t
  cross apply (values ('Jan',Jan1,Jan2),('Feb',Feb1,Feb2)
    ) v (MonthName,MonthValue1,MonthValue2)

返回:

+----+-------+-----------+-------------+-------------+
| Id | Value | MonthName | MonthValue1 | MonthValue2 |
+----+-------+-----------+-------------+-------------+
|  1 |     2 | Jan       |          25 |          35 |
|  1 |     2 | Feb       |          15 |          28 |
|  2 |     5 | Jan       |          45 |          45 |
|  2 |     5 | Feb       |          60 |          60 |
+----+-------+-----------+-------------+-------------+

或完全转置月份列,如下所示:

select Id, Value, MonthName, MonthValue
from t
  cross apply (values ('Jan1',Jan1),('Jan2',Jan2),('Feb1',Feb1),('Feb2',Feb2)
    ) v (MonthName,MonthValue)

返回:

+----+-------+-----------+------------+
| Id | Value | MonthName | MonthValue |
+----+-------+-----------+------------+
|  1 |     2 | Jan1      |         25 |
|  1 |     2 | Jan2      |         35 |
|  1 |     2 | Feb1      |         15 |
|  1 |     2 | Feb2      |         28 |
|  2 |     5 | Jan1      |         45 |
|  2 |     5 | Jan2      |         45 |
|  2 |     5 | Feb1      |         60 |
|  2 |     5 | Feb2      |         60 |
+----+-------+-----------+------------+

rextester演示:http://rextester.com/KZV45690

答案 2 :(得分:0)

这是一个您不必指定最多365个字段的选项

Declare @YourTable table (Id int,Value int,Jan1 int,Jan2 int,Feb1 int, Feb2 int)
Insert Into @YourTable values
(1,     2,      25,    35, 100, 101),
(2,     5,      45,    45, 200, 201)


Select [Id],[Value],[Month],[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23],[24],[25],[26],[27],[28],[29],[30],[31]
 From (
        Select A.Id
              ,A.Value
              ,[Month]   = Left(C.Item,3)
              ,[Col]     = substring(C.Item,4,5)
              ,[Measure] = C.Value
         From  @YourTable A
         Cross Apply (Select XMLData = cast((Select A.* for XML Raw) as xml)) B
         Cross Apply (
                        Select Item   = attr.value('local-name(.)','varchar(100)')
                              ,Value  = attr.value('.','int') 
                         From  B.XMLData.nodes('/row') as A(r)
                         Cross Apply A.r.nodes('./@*') AS B(attr)
                         Where attr.value('local-name(.)','varchar(100)') not in ('ID','Value')
                     ) C
      ) A
 Pivot (sum(Measure) For [Col] in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23],[24],[25],[26],[27],[28],[29],[30],[31]) ) p

<强>返回

enter image description here