CHill60
Для этого вам не нужен PIVOT, но вы можете сделать это с помощью обычного табличного выражения.
Первая проблема, с которой вы столкнулись, заключается в том, что вы не определили, как вы решили, что значения от 2000 года
2000 200 456 45 35
должен отображаться в той же строке, что и
2001 300 4 43 545
Это выглядит так, как будто вы используете "строка 1 из 2000 года идет со строкой 1 из 2001 года и строкой 1 из 2002 года" и т. д., Но у вас нет ничего, чтобы определить, что такое "строка 1", "строка 2" каждой группы - вам действительно нужен какой-то столбец идентификатора в вашей базовой таблице.
Я создал ваш образец данных с помощью этого:
create table #radhasapna ([Year] int, Q int, Q2 int, Q3 int, Q4 int)
insert into #radhasapna ([Year] , Q , Q2 , Q3 , Q4 ) values
(2000, 200, 456, 45, 35 ),
(2000, 200, 435, 435, 545 ),
(2000, 200, 454, 43, 45 ),
(2000, 200, 45, 435, 4 ),
(2001, 300, 4, 43, 545 ),
(2001, 300, 43, 4, 56 ),
(2001, 300, 4, 4, 4 ),
(2001, 300, 43, 43, 6 ),
(2001, 300, 4, 56, 34 ),
(2002, 400, 4, 34, 43 ),
(2002, 400, 43, 45, 6 ),
(2002, 400, 4, 45, 4 ),
(2002, 400, 43, 34, 54 ),
(2002, 400, 45, 45, 6)
Оттуда я смог получить желаемые результаты, дав каждой строке в каждом году ROW_NUMBER (), а затем просто выполнив несколько соединений с результатами.
;with cte as
(
SELECT ROW_NUMBER() OVER (PARTITION BY [Year] ORDER BY [Year]) as r,
[Year], Q, Q2, Q3, Q4
FROM #radhasapna
)
select a.*, b.*, c.*
from cte a
left outer join cte b on a.[Year] = b.[Year] and a.r = b.r
left outer join cte c on a.[Year] = c.[Year] and a.r = c.r
Мне пришлось поместить ORDER BY в оконную функцию, но константа не разрешена, поэтому я снова использовал [Year]... а это значит, что тот факт, что я получил правильные результаты, - чистая удача!
Но если я (вы!) определяю базовую таблицу следующим образом
create table #radhasapna (id int identity(1,1), [Year] int, Q int, Q2 int, Q3 int, Q4 int)
и использовать
;with cte as
(
SELECT ROW_NUMBER() OVER (PARTITION BY [Year] ORDER BY id) as r,
[Year], Q, Q2, Q3, Q4
FROM #radhasapna
)
select a.*, b.*, c.*
from cte a
left outer join cte b on a.[Year] = b.[Year] and a.r = b.r
left outer join cte c on a.[Year] = c.[Year] and a.r = c.r
тогда ваши результаты гарантированы
-----------------------------------------------------------------------------
[EDIT] - OP указал, что количество лет может варьироваться.
-----------------------------------------------------------------------------
Вам нужно будет использовать динамический SQL, если количество лет может варьироваться, что-то вроде этого:
1. Установите некоторые начальные значения, "наименьший" год (
@minY
) и количество лет (
@years
) и основа для нашего динамического sql (
@sql
)
declare @years integer = (SELECT COUNT(DISTINCT [Year]) FROM #radhasapna)
declare @minY nvarchar(10) = (SELECT CAST(MIN([Year]) as nvarchar) FROM #radhasapna)
declare @sql nvarchar(max)
set @sql = ';with cte as (
SELECT ROW_NUMBER() OVER (PARTITION BY [Year] ORDER BY id) as r,
[Year], Q, Q2, Q3, Q4
FROM #radhasapna )
SELECT '
2. Замените то, что у меня было раньше, как
select a.*, b.*, c.*
с
select a1.*, a2.*, a3.*, etc
Обратите внимание, что теперь я использую a1, a2, a3 и т. д. В качестве псевдонимов таблиц...
declare @i int = 1
WHILE @i <= @years
begin
set @sql = @sql + stuff('aXX', 2,2, @i) + '.*'
if @i < @years
begin
set @sql = @sql + ','
end
set @i = @i + 1
end
Если я
PRINT @sql
на данном этапе я получаю это
;with cte as (
SELECT ROW_NUMBER() OVER (PARTITION BY [Year] ORDER BY id) as r,
[Year], Q, Q2, Q3, Q4
FROM #radhasapna )
SELECT a1.*,a2.*,a3.*,a4.*,a5.*
3. Выясните, как выполнять соединения...
set @sql = @sql + ' from cte a1 '
set @i = 2
WHILE @i <= @years
begin
declare @s nvarchar(10) = stuff('aXX', 2,2, @i)
declare @prevS nvarchar(10) = stuff('aXX',2,2,@i-1)
set @sql = @sql + 'left outer join cte ' + @s + ' on ' + @s + '.[Year] = ' + @prevS + '.[Year] + 1 and a1.r = ' + @s + '.r '
set @i = @i + 1
end
Опять же, если я
PRINT @sql
теперь это было добавлено к концу
from cte a1
left outer join cte a2 on a2.[Year] = a1.[Year] + 1 and a1.r = a2.r
left outer join cte a3 on a3.[Year] = a2.[Year] + 1 and a1.r = a3.r
left outer join cte a4 on a4.[Year] = a3.[Year] + 1 and a1.r = a4.r
left outer join cte a5 on a5.[Year] = a4.[Year] + 1 and a1.r = a5.r
4. Все, что осталось сделать, это поставить
WHERE
предложения и
ORDER BY
предложение в конце sql и запустите его
set @sql = @sql + 'where a1.[Year] = ' + @minY + ' order by a1.r'
EXEC sp_executesql @sql