SQL Serverを使用しているため、SQL Server 2005以降を使用している場合は、このPIVOT
関数を使用できます。TestCodes
1つあたり最大2つしかないことがわかっている場合は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 FiddlewithDemoを参照してください
の値の数が不明な場合はTestCodes
、動的SQLをPIVOT
データに使用できます。
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 FiddlewithDemoを参照してください
関数にアクセスできない場合は、次のステートメント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 FiddlewithDemoを参照してください
3つすべてが同じ結果を生成します。
| IDENT | TESTCODE1 | TESTCODE2 |
----------------------------------
| 122222 | 1 | 0 |
| 123456 | 1 | 4 |
| 654321 | 2 | 6 |