Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

SQL 2012 - Pivot dan Unpivot

Anda dapat menggunakan SQL dinamis untuk mengubah posisi tabel:

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

Keluaran:

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

Jika Anda ingin zeros pada posisi yang hilang, Anda dapat menggunakan ISNULL/COALESCE . Ketahuilah bahwa tidak semua tipe data dapat diganti dengan 0 (int)

LiveDemo2

EDIT:

FORMATMESSAGE adalah cara yang bagus untuk mengganti %s dengan tali. Itu dapat dengan mudah diubah dengan REPLACE sederhana :

 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;

Cara kerjanya:

  1. Buat [year_month] kolom di subkueri
  2. UNPIVOT data (kolom ke baris)
  3. PIVOT hasil (baris ke kolom)
  4. Bungkus dengan dynamic-SQL untuk memungkinkan pembuatan kolom tanpa mengetahui [year_month] sebelumnya.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kueri SQL Server pilih 1 dari setiap sub-grup

  2. Pernyataan INSERT EXEC tidak dapat disarangkan. Menangani kesalahan

  3. sql query dengan self join

  4. Bandingkan string yang dipisahkan koma dalam SQL

  5. Cara memasukkan baris baru dengan benar di nvarchar