2016-03-14 7 views
0

Я суммированы данные в таблице, которая похожа на это:SQL 2012 - Pivot и UNPIVOT

Customer Year Month No_trans spend points 
1  2015 1  30  400 10 
1  2015 2  20  150 5 
1  2015 3  10  500 15 
2  2015 1  5  100 7 

Я хотел бы попробовать и использовать Pivot/UNPIVOT, чтобы изменить это, возможно ли это?

?????? Customer 2015_1 2015_2 2015_3 
No_trans 1  30  20  10    
Spend 1  400 150 500 
Points 1  10  5  15 
No_trans 2  5  0  0    
Spend 2  100 0  0 
Points 2  7  0  0 

Благодаря

+0

Не могли бы Вы уточнить причиненные Вами в результате? – Juhi

+0

'2 2015 1 5 100 7' Вы должны иметь значения в столбце' 2015_1' при желаемом результате, а не '2015_3' – lad2025

ответ

1

Вы можете использовать динамический 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 col_name, customer, %s 
FROM (SELECT [year_month] = CONCAT([Year], ''_'', [Month]), 
      Customer, No_Trans, spend, points 
     FROM #tab) AS sub 
UNPIVOT 
(
    val FOR col_name IN (No_trans, spend, points) 
) AS unpvt 
PIVOT 
(
    MAX(val) FOR [year_month] IN (%s) 
) AS pvt 
ORDER BY customer, col_name;', @cols, @cols); 

EXEC [dbo].[sp_executesql] @query; 

LiveDemo

Выход:

╔══════════╦══════════╦════════╦════════╦════════╗ 
║ col ║ customer ║ 2015_1 ║ 2015_2 ║ 2015_3 ║ 
╠══════════╬══════════╬════════╬════════╬════════╣ 
║ No_Trans ║  1 ║  30 ║  20 ║  10 ║ 
║ points ║  1 ║  10 ║  5 ║  15 ║ 
║ spend ║  1 ║ 400 ║ 150 ║ 500 ║ 
║ No_Trans ║  2 ║  5 ║  ║  ║ 
║ points ║  2 ║  7 ║  ║  ║ 
║ spend ║  2 ║ 100 ║  ║  ║ 
╚══════════╩══════════╩════════╩════════╩════════╝ 

Если вы хотите zeros в отсутствующем положении, вы можете использовать ISNULL/COALESCE. Имейте в виду, что не каждый datatatype может быть заменен 0 (int)

LiveDemo2

EDIT:

FORMATMESSAGE это причудливый способ заменить %s шпагатом. Это может быть легко изменено путем простого REPLACE:

DECLARE @query NVARCHAR(MAX) = 
N'SELECT col1, col2, <placeholder> 
    FROM ... 
    ... 
    PIVOT(MAX(col) IN col2 IN (<placeholder>) 
    ...'; 

SET @query = REPLACE(@query, '<placeholder', @cols); 

-- for debug 
PRINT @query; 

Как это работает:

  1. Сформировать [year_month] колонки в подзапросе
  2. UNPIVOT данные (столбцы грести)
  3. PIVOT результатом (строки в столбцы)
  4. Оберните его динамическим SQL, чтобы разрешить генерировать столбцы, не зная, [year_month] в объявлении Вэнс.
+0

Привет, спасибо за вашу помощь, я хотел бы заказать col по определенным строкам, как я могу включить заказ клиентом , case col, когда «No_trans» затем 1, когда «Проведите», затем 2, когда «указывает», затем 3 else 4 заканчивается. – HL8

+0

Привет, lad2025, я новичок в динамическом sql и особенно поворачиваюсь, вы можете пройти через кода и объяснить простым языком, что каждый раздел означает или делает? например. SELECT col_name, клиент,% s, что делает «% s»? Или есть некоторые, где онлайн вы можете направить меня читать? – HL8

+0

@ HL8 Пожалуйста, уточните обновление – lad2025