仅仅因为我喜欢枢轴,我将向您展示如何使用 PIVOT 函数来完成。为了使用 PIVOT 函数获得结果,您首先需要对多个列进行score
UNPIVOTnotes
和createdate
. unpivot 过程会将多列转换为多行。
由于您使用的是 SQL Server 2008,因此您可以使用 CROSS APPLY 取消透视数据,查询的第一部分将类似于:
;with cte as
(
select id, score, notes, createdate,
row_number() over(partition by id order by createdate) seq
from yourtable
)
select id, col, value
from
(
select t.id,
col = col + cast(seq as varchar(10)),
value
from cte t
cross apply
(
values
('score', cast(score as varchar(10))),
('notes', notes),
('date', convert(varchar(10), createdate, 120))
) c (col, value)
) d;
请参阅SQL Fiddle with Demo。这样做会使您的数据采用以下格式:
| ID | COL | VALUE |
| 1661 | score1 | 9.20 |
| 1661 | notes1 | 8.0 on Sept 2010 |
| 1661 | date1 | 2010-07-22 |
| 1661 | score2 | 7.60 |
| 1661 | notes2 | (null) |
| 1661 | date2 | 2010-11-04 |
| 1661 | score3 | 7.90 |
现在您可以应用 PIVOT 功能:
;with cte as
(
select id, score, notes, createdate,
row_number() over(partition by id order by createdate) seq
from yourtable
)
select id, col, value
from
(
select t.id,
col = col + cast(seq as varchar(10)),
value
from cte t
cross apply
(
values
('score', cast(score as varchar(10))),
('notes', notes),
('date', convert(varchar(10), createdate, 120))
) c (col, value)
) d
pivot
(
max(value)
for col in (score1, notes1, date1, score2, notes2, date2,
score3, notes3, date3, score4, notes4, date4,
score5, notes5, date5)
) piv;
请参阅SQL Fiddle with Demo。
然后,如果您要为 each 有一个未知数量的值id
,您可以实现动态 SQL 来获得结果:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(col + cast(seq as varchar(10)))
from
(
select row_number() over(partition by id order by createdate) seq
from yourtable
) d
cross apply
(
select 'score', 1 union all
select 'notes', 2 union all
select 'date', 3
) c (col, so)
group by seq, col, so
order by seq, so
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT id, ' + @cols + '
from
(
select t.id,
col = col + cast(seq as varchar(10)),
value
from
(
select id, score, notes, createdate,
row_number() over(partition by id order by createdate) seq
from yourtable
) t
cross apply
(
values
(''score'', cast(score as varchar(10))),
(''notes'', notes),
(''date'', convert(varchar(10), createdate, 120))
) c (col, value)
) x
pivot
(
max(value)
for col in (' + @cols + ')
) p '
execute sp_executesql @query;
请参阅SQL Fiddle with Demo。两个版本都给出了结果:
| ID | SCORE1 | NOTES1 | DATE1 | SCORE2 | NOTES2 | DATE2 | SCORE3 | NOTES3 | DATE3 | SCORE4 | NOTES4 | DATE4 | SCORE5 | NOTES5 | DATE5 |
| 1661 | 9.20 | 8.0 on Sept 2010 | 2010-07-22 | 7.60 | (null) | 2010-11-04 | 7.90 | (null) | 2011-06-10 | 8.30 | (null) | 2011-09-28 | 7.90 | (null) | 2012-01-20 |