由于您使用的是 SQL Server,如果您使用的是 SQL Server 2005+,那么您可以使用该PIVOT
功能。如果您知道TestCodes
每个最多只能有两个,ident
那么您可以对这些值进行硬编码:
select ident,
[1] TestCode1,
[2] TestCode2
from
(
SELECT s.ident AS Ident,
p.prgc AS TestCode,
row_number() over(partition by s.ident order by p.prgc) rn
FROM student s
LEFT OUTER JOIN proghist p
on s.ident = p.ident
) src
pivot
(
max(TestCode)
for rn in ([1], [2])
) piv
请参阅带有演示的 SQL Fiddle
如果您有未知数量的 值TestCodes
,则可以PIVOT
对数据使用动态 SQL:
DECLARE @cols AS NVARCHAR(MAX),
@colsPivot AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(rn)
FROM
(
select cast(row_number() over(partition by s.ident order by p.prgc) as varchar(50)) rn
FROM student s
LEFT OUTER JOIN proghist p
on s.ident = p.ident
) src
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select @colsPivot = STUFF((SELECT distinct ',' + QUOTENAME(rn) + ' as TestCode'+rn
FROM
(
select cast(row_number() over(partition by s.ident order by p.prgc) as varchar(50)) rn
FROM student s
LEFT OUTER JOIN proghist p
on s.ident = p.ident
) src
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT Ident, ' + @colsPivot + ' from
(
SELECT s.ident AS Ident,
p.prgc AS TestCode,
row_number() over(partition by s.ident order by p.prgc) rn
FROM student s
LEFT OUTER JOIN proghist p
on s.ident = p.ident
) src
pivot
(
max(TestCode)
for rn in (' + @cols + ')
) p '
execute(@query)
请参阅带有演示的 SQL Fiddle
如果您无权访问该PIVOT
函数,则可以使用带有CASE
语句的聚合函数:
select ident,
max(case when rn = 1 then testcode else '' end) TestCode1,
max(case when rn = 2 then testcode else '' end) TestCode2
from
(
SELECT s.ident AS Ident,
p.prgc AS TestCode,
row_number() over(partition by s.ident order by p.prgc) rn
FROM student s
LEFT OUTER JOIN proghist p
on s.ident = p.ident
) src
group by ident
请参阅带有演示的 SQL Fiddle
这三个都将产生相同的结果:
| IDENT | TESTCODE1 | TESTCODE2 |
----------------------------------
| 122222 | 1 | 0 |
| 123456 | 1 | 4 |
| 654321 | 2 | 6 |