由于您想要 PIVOT 两列,我的建议是先取消date
和result
列,然后应用 PIVOT 函数。
unpivot 过程会将两列转换为date
多result
行:
select userid,
col = test +'_'+cast(ranking as varchar(10))+'_'+ col,
value
from yourtable t1
cross apply
(
select 'time', convert(varchar(10), date, 120) union all
select 'result', cast(result as varchar(10))
) c (col, value)
请参阅演示。这会给你一个结果:
| USERID | COL | VALUE |
--------------------------------------
| 1 | PSA_1_time | 1997-05-20 |
| 1 | PSA_1_result | 2 |
| 1 | PSA_2_time | 1998-05-07 |
| 1 | PSA_2_result | 4 |
| 1 | PSA_3_time | 1999-06-08 |
现在您有了这种格式的数据,那么您可以应用 pivot 来获取每个项目的max
/min
值col
:
如果您的列数有限,则可以对查询进行硬编码:
select *
from
(
select userid,
col = test +'_'+cast(ranking as varchar(10))+'_'+ col,
value
from yourtable t1
cross apply
(
select 'time', convert(varchar(10), date, 120) union all
select 'result', cast(result as varchar(10))
) c (col, value)
) d
pivot
(
max(value)
for col in (PSA_1_time, PSA_1_result,
PSA_2_time, PSA_2_result,
PSA_3_time, PSA_3_result,
PSA_4_time, PSA_4_result,
PSA_5_time, PSA_5_result)
) piv;
请参阅带有演示的 SQL Fiddle
如果您有未知列,那么您将需要使用动态 SQL:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(test +'_'+cast(ranking as varchar(10))+'_'+ col)
from yourtable
cross apply
(
select 'time', 1 union all
select 'result', 2
) c (col, so)
group by test, ranking, col, so
order by Ranking, so
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT userid,' + @cols + '
from
(
select userid,
col = test +''_''+cast(ranking as varchar(10))+''_''+ col,
value
from yourtable t1
cross apply
(
select ''time'', convert(varchar(10), date, 120) union all
select ''result'', cast(result as varchar(10))
) c (col, value)
) x
pivot
(
max(value)
for col in (' + @cols + ')
) p '
execute sp_executesql @query;
请参阅SQL Fiddle with Demo。两个版本都会给出结果:
| USERID | PSA_1_TIME | PSA_1_RESULT | PSA_2_TIME | PSA_2_RESULT | PSA_3_TIME | PSA_3_RESULT | PSA_4_TIME | PSA_4_RESULT | PSA_5_TIME | PSA_5_RESULT |
------------------------------------------------------------------------------------------------------------------------------------------------------
| 1 | 1997-05-20 | 2 | 1998-05-07 | 4 | 1999-06-08 | 6 | 2001-06-08 | 8 | 2004-06-08 | 0 |
| 3 | 1992-05-07 | 4 | 1994-06-08 | 6 | (null) | (null) | (null) | (null) | (null) | (null) |
| 4 | 2006-06-08 | 8 | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) |