如果可能的话,我想使用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
答案 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 |
+----+---------------------+-----+------+------+