T-SQL PIVOT数据从长格式到宽格式的日期

时间:2017-02-27 22:32:53

标签: sql-server

如果可能的话,我想使用t-sql pivot函数将数据从long扩展为wide。我目前的表格如下:

ID  DATE        NUM VALUE
1   2005-01-20  29  197
1   2005-01-20  28  58
1   2005-01-20  30  90
1   2005-02-08  29  210
1   2005-02-08  30  133
1   2005-02-08  28  67
2   2005-01-10  28  87
2   2005-01-10  30  119
2   2005-07-11  28  77
2   2005-07-11  29  174

输出应如下所示:

ID  DATE        V28 V29  V30
1   2005-01-20  58  197  90
1   2005-02-08  67  210  133
2   2005-01-10  87  NULL 119
2   2005-07-11  77  74   NULL

1 个答案:

答案 0 :(得分:3)

pivot()的传统交叉表/条件聚合版本如下:

select 
    id
  , date
  , v28 = sum(case when num = 28 then value end)
  , v29 = sum(case when num = 29 then value end)
  , v30 = sum(case when num = 30 then value end)
from t
group by id, date

pivot()版本:

select
    Id
  , date
  , v28
  , v29
  , v30
from 
  (select id, date, num = 'v'+convert(varchar(10),num), value
    from t) as t
  pivot (sum(value) for num in (v28, v29, v30)) pvt

动态透视代码生成:

declare @cols nvarchar(max);
declare @sql  nvarchar(max);
  select @cols = stuff((
    select distinct 
      ', ' + 'v'+convert(varchar(10),num)
      from t 
      order by 1
      for xml path (''), type).value('.','nvarchar(max)')
    ,1,2,'')
select  @sql = '
 select Id, date, ' + @cols + '
  from  (
    select Id, date, num = ''v''+convert(varchar(10),num), value
      from t
      ) as t
 pivot (sum([value]) for [num] in (' + @cols + ') ) p'
select @sql
exec(@sql);

生成以下内容:

select Id, date, v28, v29, v30
  from  (
    select Id, date, num = 'v'+convert(varchar(10),num), value
      from t
      ) as t
 pivot (sum([value]) for [num] in (v28, v29, v30) ) p

在这里测试它们:http://rextester.com/ZJS18834

结果(按ID,日期排序)

+----+---------------------+-----+------+------+
| id |        date         | v28 | v29  | v30  |
+----+---------------------+-----+------+------+
|  1 | 20.01.2005 00:00:00 |  58 | 197  | 90   |
|  1 | 08.02.2005 00:00:00 |  67 | 210  | 133  |
|  2 | 10.01.2005 00:00:00 |  87 | NULL | 119  |
|  2 | 11.07.2005 00:00:00 |  77 | 174  | NULL |
+----+---------------------+-----+------+------+