Я создал таблицу с именем «Table2», содержащую данные, которые вы показали выше под заголовком таблицы 2.
Вот SQL, который я использовал в SQL Server 2008.
WITH RankedValues AS
(
SELECT
FID AS ID,
YearS,
ROW_NUMBER() OVER(PARTITION BY FID ORDER BY YearS) AS YearSRank,
Val
FROM
Table2
)
SELECT
ID,
MAX((CASE WHEN YearSRank = 1 THEN YearS ELSE 0 END)) AS Yr1,
MAX((CASE WHEN YearSRank = 1 THEN Val ELSE '' END)) AS Val1,
MAX((CASE WHEN YearSRank = 2 THEN YearS ELSE 0 END)) AS Yr2,
MAX((CASE WHEN YearSRank = 2 THEN Val ELSE '' END)) AS Val2,
MAX((CASE WHEN YearSRank = 3 THEN YearS ELSE 0 END)) AS Yr3,
MAX((CASE WHEN YearSRank = 3 THEN Val ELSE '' END)) AS Val3,
MAX((CASE WHEN YearSRank = 4 THEN YearS ELSE 0 END)) AS Yr4,
MAX((CASE WHEN YearSRank = 4 THEN Val ELSE '' END)) AS Val4
FROM
RankedValues
GROUP BY
ID
Приведенный выше SQL приведет к следующему:
ID Yr1 Val1 Yr2 Val2 Yr3 Val3 Yr4 Val4
---------------------------------------------------------------------
1 2008 Up 2009 Down 2010 Up 0
2 2000 Up 2001 Down 2002 Up 2003 Up
3 2009 Down 2010 Up 0 0
Причина, по которой вы не видите значения NULL
, связана с ELSE
в каждом операторе CASE
.Если у вас есть NULL
значения, просто удалите ELSE 0
и ELSE ''
, как требуется.
В настоящее время я не знаю, возможно ли сделать этот универсальный, например: обработать неизвестное количестворазличных FID, поскольку это также будет означать генерацию имен столбцов (Yr1, al1, Yr2 и т. д.) в общем.
Вы могли бы достичь этого с помощью динамического SQL, но, как я не большой поклонникдинамический SQL Я бы попробовал найти другой способ решения этой проблемы.
- Правка (добавлен сводный подход для полноты) -
Я посмотрел ссылку, опубликованную Джо Стефанелли, и добавилSQL ниже для вашего требования.Хотя мне не нравится идея динамического SQL, я не смог найти другой способ в этом конкретном случае.
DECLARE @query VARCHAR(4000)
DECLARE @years VARCHAR(2000)
SELECT @years = STUFF((
SELECT DISTINCT
'],[' + ltrim(str(YearS))
FROM Table2
ORDER BY '],[' + ltrim(str(YearS))
FOR XML PATH('')), 1, 2, '') + ']'
SET @query =
'SELECT * FROM
(
SELECT FID AS ID,YearS,Val
FROM Table2
) AS t
PIVOT (MAX(Val) FOR YearS IN (' + @years + ')) AS pvt'
EXECUTE (@query)
Это приведет к следующему:
ID 2000 2001 2002 2003 2008 2009 2010
---------------------------------------------------------
1 NULL NULL NULL NULL Up Down Up
2 Up Down Up Up NULL NULL NULL
3 NULL NULL NULL NULL NULL Down Up
В зависимости от того, какойформатировать и подходить вам больше всего нравится, по крайней мере, у вас есть варианты.