PIVOT
を実行するには 2 つの方法があります 値をハードコーディングする場合は静的、実行時に列が決定される場合は動的です。
動的なバージョンが必要な場合でも、静的な PIVOT
から始める方が簡単な場合があります そして、動的なものに向けて取り組みます。
静的バージョン:
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
プレ>デモによる SQL Fiddle を参照してください
変換される値がわからない場合は、動的 SQL を使用できます。
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)
プレ>デモによる SQL Fiddle を参照してください。
どちらのバージョンでも同じ結果が得られます。
PIVOT
がない場合は、答えを締めくくります。 関数の場合、CASE
を使用してこの結果を取得できます および集約関数: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
プレ>SQL Fiddle with Demo を参照してください