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

Bagaimana cara mengubah nilai baris menjadi kolom dengan jumlah kolom dinamis?

Saran saya setiap kali Anda bekerja dengan PIVOT adalah untuk selalu menulis kueri terlebih dahulu dengan nilai-nilai yang dikodekan secara keras, kemudian Anda dapat dengan mudah mengonversi kueri ke solusi dinamis.

Karena Anda akan memiliki beberapa nilai columnC yang akan diubah menjadi kolom, maka Anda perlu melihat menggunakan row_number() fungsi windowing untuk menghasilkan urutan unik untuk setiap columnc berdasarkan nilai columnA dan columnB .

Titik awal untuk kueri Anda adalah:

select [ColumnA],
  [ColumnB],
  [ColumnC],
  'SampleTitle'+
  cast(row_number() over(partition by columna, columnb
                          order by columnc) as varchar(10)) seq
from DataSource;

Lihat Demo. Kueri ini akan menghasilkan daftar nama kolom baru SampleTitle1 , dll:

| COLUMNA | COLUMNB | COLUMNC |          SEQ |
|---------|---------|---------|--------------|
|    5060 |    1006 |  100118 | SampleTitle1 |
|    5060 |    1006 |  100119 | SampleTitle2 |
|    5060 |    1006 |  100120 | SampleTitle3 |

Anda kemudian dapat menerapkan pivot pada columnC dengan nama kolom baru yang terdaftar di seq :

select columnA, columnB, 
  SampleTitle1, SampleTitle2, SampleTitle3
from
(
   select [ColumnA],
    [ColumnB],
    [ColumnC],
    'SampleTitle'+
      cast(row_number() over(partition by columna, columnb
                              order by columnc) as varchar(10)) seq
   from DataSource
) d
pivot
(
  max(columnc)
  for seq in (SampleTitle1, SampleTitle2, SampleTitle3)
) piv;

Lihat SQL Fiddle dengan Demo.

Setelah Anda memiliki logika yang benar, Anda dapat mengonversi data ke SQL dinamis. Kuncinya di sini adalah menghasilkan daftar nama kolom baru. Saya biasanya menggunakan FOR XML PATH untuk ini mirip dengan:

select STUFF((SELECT distinct ',' + QUOTENAME(seq) 
                from
                (
                  select 'SampleTitle'+
                    cast(row_number() over(partition by columna, columnb
                                            order by columnc) as varchar(10)) seq
                  from DataSource
                ) d
        FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'')

Lihat Demo. Setelah Anda memiliki daftar nama kolom, maka Anda akan membuat string sql Anda untuk dieksekusi, kode lengkapnya adalah:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(seq) 
                    from
                    (
                      select 'SampleTitle'+
                        cast(row_number() over(partition by columna, columnb
                                                order by columnc) as varchar(10)) seq
                      from DataSource
                    ) d
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT columnA, ColumnB,' + @cols + ' 
             from 
             (
               select [ColumnA],
                [ColumnB],
                [ColumnC],
                ''SampleTitle''+
                  cast(row_number() over(partition by columna, columnb
                                          order by columnc) as varchar(10)) seq
               from DataSource
            ) x
            pivot 
            (
                max(columnc)
                for seq in (' + @cols + ')
            ) p '

execute sp_executesql @query;

Lihat SQL Fiddle dengan Demo. Ini memberikan hasil:

| COLUMNA | COLUMNB | SAMPLETITLE1 | SAMPLETITLE2 | SAMPLETITLE3 |
|---------|---------|--------------|--------------|--------------|
|    5060 |    1006 |       100118 |       100119 |       100120 |
|    5060 |    1007 |       100121 |       100122 |       (null) |
|    5060 |    1012 |       100123 |       (null) |       (null) |



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Pengantar Tabel Sementara di SQL Server

  2. Cara Memperbaiki "Prosedur mengharapkan parameter '@ pernyataan' dari jenis 'ntext/nchar/nvarchar'." Kesalahan dalam SQL Server

  3. Solusi untuk:Simpan pembaruan, sisipkan, atau hapus pernyataan yang memengaruhi jumlah baris yang tidak terduga (0)

  4. Bagaimana Fungsi STR() Bekerja di SQL Server (T-SQL)

  5. Memformat Nomor Telepon di SQL Server (T-SQL)