Можете да използвате динамичен SQL за транспониране на таблица:
DECLARE @cols NVARCHAR(MAX) =STUFF((SELECT DISTINCT ',' + QUOTENAME(CONCAT([Year], '_', [Month])) FROM #tab FOR XML PATH('') , TYPE ).value('.', 'NVARCHAR(MAX)') , 1, 1, '');DECLARE @query NVARCHAR(MAX) =FORMATMESSAGE(N'SELECT име на колона, клиент, %sFROM (ИЗБЕРЕТЕ [година_месец] =CONCAT([Година], ''_'', [Месец]), Клиент, No_Trans, разходи, точки ОТ #tab) AS subUNPIVOT( val FOR col_name IN (No_trans, разходи, точки)) AS unpvtPIVOT( MAX(val ) ЗА [година_месец] В (%s)) AS pvtORDER BY customer, col_name;', @cols, @cols); EXEC [dbo].[sp_executesql] @query;
Изход:
<предварителен код>╔══════════╦══════════╦════════╦══════════ ═════╗║ COL ║ Клиент ║ 2015_1 ║ 2015_2 ║ 2015_3 ║╠══════════╬══════════╬════════╬═ ═══════╬════════╣║ no_trans ║ 1 ║ 30 ║ 20 ║ 10 ║║ Точки ║ 1 ║ 10 ║ 5 ║ 15 ║║ харчат ║ 1 ║ 400 ║ 150 ║ 500 ║ ║ no_trans ║ 2 ║ 5 ║ ║ ║║ точки ║ 2 ║ 7 ║ ║ ║║ ║║ ║║ ║║ ║ 2 ║ 100 ║ ║ ║╚══════════╩══════════╩ ║╚══════════╩══════════╩ ║╚══════════╩══════════╩ ║╚══════════╩══════════╩ ║╚══════════╩══════════╩ ║╚══════════╩══════════╩ ║╚══════════╩══════════╩ ║╚══════════╩══════════╩ ════════╩════════╩════════╝
Ако искате нули
при липсваща позиция можете да използвате ISNULL/COALESCE
. Имайте предвид, че не всеки тип данни може да бъде заменен с 0 (int)
РЕДАКТИРАНЕ:
FORMATMESSAGE
е фантастичен начин за замяна на %s
с низ. Може лесно да се промени чрез просто REPLACE
:
DECLARE @query NVARCHAR(MAX) =N'SELECT col1, col2, FROM ... ... PIVOT( MAX(col) IN col2 IN () ...'; SET @query =REPLACE(@query, '
Как работи:
- Генериране на
[година_месец]
колона в подзаявка UNPIVOT
данни (колони към ред)ОСНОВА ИНФОРМАЦИЯ
резултат (редове към колони)- Обвийте го с динамичен SQL, за да позволите генериране на колони, без да знаете
[year_month]
предварително.