Ada dua cara untuk melakukan PIVOT
statis di mana Anda mengkodekan nilai-nilai dan dinamis di mana kolom ditentukan saat Anda mengeksekusi.
Meskipun Anda menginginkan versi dinamis, terkadang lebih mudah untuk memulai dengan PIVOT
statis dan kemudian bekerja menuju yang dinamis.
Versi Statis:
SELECT studentid, name, sex,[C], [C++], [English], [Database], [Math], total, average
from
(
select s1.studentid, name, sex, subjectname, score, total, average
from Score s1
inner join
(
select studentid, sum(score) total, avg(score) average
from score
group by studentid
) s2
on s1.studentid = s2.studentid
) x
pivot
(
min(score)
for subjectname in ([C], [C++], [English], [Database], [Math])
) p
Lihat SQL Fiddle dengan demo
Sekarang, jika Anda tidak tahu nilai-nilai yang akan diubah maka Anda dapat menggunakan SQL Dinamis untuk ini:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(SubjectName)
from Score
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT studentid, name, sex,' + @cols + ', total, average
from
(
select s1.studentid, name, sex, subjectname, score, total, average
from Score s1
inner join
(
select studentid, sum(score) total, avg(score) average
from score
group by studentid
) s2
on s1.studentid = s2.studentid
) x
pivot
(
min(score)
for subjectname in (' + @cols + ')
) p '
execute(@query)
Lihat SQL Fiddle dengan Demo
Kedua versi akan memberikan hasil yang sama.
Hanya untuk melengkapi jawabannya, jika Anda tidak memiliki PIVOT
fungsi, maka Anda bisa mendapatkan hasil ini menggunakan CASE
dan fungsi agregat:
select s1.studentid, name, sex,
min(case when subjectname = 'C' then score end) C,
min(case when subjectname = 'C++' then score end) [C++],
min(case when subjectname = 'English' then score end) English,
min(case when subjectname = 'Database' then score end) [Database],
min(case when subjectname = 'Math' then score end) Math,
total, average
from Score s1
inner join
(
select studentid, sum(score) total, avg(score) average
from score
group by studentid
) s2
on s1.studentid = s2.studentid
group by s1.studentid, name, sex, total, average
Lihat SQL Fiddle dengan Demo