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

Kueri Tab Silang dengan Kolom Dinamis di SQL Server 2005 ke atas

Ada dua cara untuk melakukan PIVOT statis di mana Anda mengkodekan nilai-nilai dan dinamis di mana kolom ditentukan saat Anda mengeksekusi.

Meskipun Anda menginginkan versi dinamis, terkadang lebih mudah untuk memulai dengan PIVOT statis dan kemudian bekerja menuju yang dinamis.

Versi Statis:

SELECT studentid, name, sex,[C], [C++], [English], [Database], [Math], total, average
from 
(
  select s1.studentid, name, sex, subjectname, score, total, average
  from Score s1
  inner join
  (
    select studentid, sum(score) total, avg(score) average
    from score
    group by studentid
  ) s2
    on s1.studentid = s2.studentid
) x
pivot 
(
   min(score)
   for subjectname in ([C], [C++], [English], [Database], [Math])
) p

Lihat SQL Fiddle dengan demo

Sekarang, jika Anda tidak tahu nilai-nilai yang akan diubah maka Anda dapat menggunakan SQL Dinamis untuk ini:

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

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(SubjectName) 
                    from Score
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')



set @query = 'SELECT studentid, name, sex,' + @cols + ', total, average
              from 
             (
                select s1.studentid, name, sex, subjectname, score, total, average
                from Score s1
                inner join
                (
                  select studentid, sum(score) total, avg(score) average
                  from score
                  group by studentid
                ) s2
                  on s1.studentid = s2.studentid
            ) x
            pivot 
            (
                min(score)
                for subjectname in (' + @cols + ')
            ) p '

execute(@query)

Lihat SQL Fiddle dengan Demo

Kedua versi akan memberikan hasil yang sama.

Hanya untuk melengkapi jawabannya, jika Anda tidak memiliki PIVOT fungsi, maka Anda bisa mendapatkan hasil ini menggunakan CASE dan fungsi agregat:

select s1.studentid, name, sex, 
  min(case when subjectname = 'C' then score end) C,
  min(case when subjectname = 'C++' then score end) [C++],
  min(case when subjectname = 'English' then score end) English,
  min(case when subjectname = 'Database' then score end) [Database],
  min(case when subjectname = 'Math' then score end) Math,
  total, average
from Score s1
inner join
(
  select studentid, sum(score) total, avg(score) average
  from score
  group by studentid
) s2
  on s1.studentid = s2.studentid
group by s1.studentid, name, sex, total, average

Lihat SQL Fiddle dengan Demo



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Memecahkan Masalah Kemacetan I/O Disk

  2. MSDTC di server 'server tidak tersedia'

  3. Cara Mengembalikan Semua Batasan Kunci Asing yang Dinonaktifkan di SQL Server (Contoh T-SQL)

  4. Tambahkan login dan sambungkan ke SQL dengan SQL Server Authentication

  5. Karakter Non-Angka yang Mengembalikan Positif saat menggunakan ISNUMERIC() di SQL Server