Мое предложение всегда состоит в том, чтобы сначала написать свой запрос в виде жестко запрограммированной или статической версии, прежде чем погрузиться в динамический SQL. Это позволит вам получить желаемый конечный результат с меньшим подмножеством данных, и вы сможете убедиться в правильности логики.
Я бы решил эту проблему, выполнив сначала UNPIVOT
из двух Revenue
столбцов, а затем рассмотрим применение функции PIVOT
. Для UNPIVOT
вы можете использовать либо функцию UNPIVOT
, либо CROSS APPLY
с UNION ALL
для преобразования двух Revenue
столбцов в один столбец. Статическая версия запроса будет выглядеть следующим образом:
select *
from
(
select
t.[Scheme Code],
new_colname = concat(t.[MonthYear], ' ', r.colname),
r.colvalue
from yourtable t
cross apply
(
select 'A', Revenue union all
select 'B', Revenue2
) r (colname, colvalue)
) d
pivot
(
sum(colvalue)
for new_colname in ([2018.1 A], [2018.2 A], [2018.3 A], [2018.1 B], [2018.2 B], [2018.3 B])
) p;
Вы заметите, что в CROSS APPLY
я добавил столбец с A
или B
, который я использую для идентификации столбцов Revenue
или Revenue2
. Затем он используется для создания новых имен столбцов для PIVOT
.
Это должно привести к желаемому результату. Теперь, чтобы сделать это динамически, вам просто нужно преобразовать SQL в динамический код. Для получения результата вы можете использовать следующее:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
Select @cols = STUFF((SELECT ',' + QUOTENAME(concat([MonthYear], x.col))
from yourtable
cross join (select col = ' A' union all select ' B') x
group by [MonthYear], x.col
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT *
FROM
(
select
t.[Scheme Code],
new_colname = concat(t.[MonthYear], '' '', r.colname),
r.colvalue
from yourtable t
cross apply
(
select ''A'', Revenue union all
select ''B'', Revenue2
) r (colname, colvalue)
) a
PIVOT
(
sum(colvalue) for new_colname in (' + @cols + ')
) as x
ORDER BY [Scheme Code]';
exec sp_executesql @query;
Оба они должны давать одинаковые результаты ( dbfiddle demo )