Я бы предложил использовать условное агрегирование :
DECLARE @tbl TABLE(ID INT, [year] INT, reading INT, writing INT, spelling INT);
INSERT INTO @tbl VALUES
(33087,7,625,620,686)
,(33087,8,544,560,541)
,(33205,7,559,572,497)
,(33205,8,599,560,612)
,(33902,7,500,484,464)
,(33902,8,607,560,686);
- запрос:
SELECT t.ID
,MAX(CASE WHEN t.[year]=7 THEN t.[year] END) AS year_1
,MAX(CASE WHEN t.[year]=7 THEN t.reading END) AS reading_1
,MAX(CASE WHEN t.[year]=7 THEN t.writing END) AS writing_1
,MAX(CASE WHEN t.[year]=7 THEN t.spelling END) AS spelling_1
,MAX(CASE WHEN t.[year]=8 THEN t.[year] END) AS year_2
,MAX(CASE WHEN t.[year]=8 THEN t.reading END) AS reading_2
,MAX(CASE WHEN t.[year]=8 THEN t.writing END) AS writing_2
,MAX(CASE WHEN t.[year]=8 THEN t.spelling END) AS spellingg_
--add more blocks if needed
FROM @tbl t
GROUP BY t.ID;
PIVOT
ограничен одним столбцом,В вашем случае вы хотите «повернуть» несколько столбцов одновременно.Этот подход обеспечивает максимальный контроль над тем, как вы вычисляете / агрегируете свои данные, если на ID и год приходится более одной строки.
Еще одно преимущество: это довольно просто создать динамически.В этом случае вам придется просматривать свои данные, находить текущие годы и создавать один блок в год.Затем вы выполняете оператор.
Другим подходом было условное объединение :
WITH IDsOnly AS
(
SELECT t.ID
FROM @tbl t
GROUP BY t.ID
)
SELECT IDsOnly.ID
,A.[year] AS year_1,A.reading AS reading_1,A.writing AS writing_1,A.spelling AS spelling_1
,B.[year] AS year_2,B.reading AS reading_2,B.writing AS writing_2,B.spelling AS spelling_2
FROM IDsOnly
LEFT JOIN(SELECT * FROM @tbl t7 WHERE t7.[year]=7) AS A ON IDsOnly.ID=A.ID
LEFT JOIN(SELECT * FROM @tbl t7 WHERE t7.[year]=8) AS B ON IDsOnly.ID=B.ID;
--Add more joins if needed...