Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

SQL 2012 – Pivot und Unpivot

Sie könnten dynamisches SQL verwenden, um die Tabelle zu transponieren:

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

Ausgabe:

╔══════════╦══════════╦════════╦════════╦════════╗
║   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 ║        ║        ║
╚══════════╩══════════╩════════╩════════╩════════╝

Wenn Sie zeros wollen an fehlender Position könnten Sie ISNULL/COALESCE verwenden . Beachten Sie, dass nicht jeder Datentyp durch 0 (int) ersetzt werden kann

LiveDemo2

BEARBEITEN:

FORMATMESSAGE ist eine schicke Art, %s zu ersetzen mit Schnur. Es könnte einfach durch einfaches REPLACE geändert werden :

 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;

Wie es funktioniert:

  1. Erzeuge [year_month] Spalte in der Unterabfrage
  2. UNPIVOT Daten (Spalten bis Zeilen)
  3. PIVOT Ergebnis (Zeilen zu Spalten)
  4. Umschließen Sie es mit dynamischem SQL, um das Generieren von Spalten zu ermöglichen, ohne [year_month] zu kennen im Voraus.