Dalam artikel saya sebelumnya tentang operator pivot dasar, kita melihat bagaimana operator pivot dapat digunakan untuk mengonversi baris menjadi kolom, menghasilkan tabel pivot. Kami melihat bahwa ada tiga langkah utama untuk membuat tabel pivot. Langkah pertama adalah memilih basis data. Langkah kedua adalah mengonversi data dasar menjadi ekspresi bernilai tabel, dan langkah terakhir melibatkan penerapan operator pivot ke data sementara, yang menghasilkan tabel pivot.
Lihatlah contoh di bawah ini.
USE schooldb SELECT * FROM (SELECT city, total_score FROM student ) AS StudentTable PIVOT( AVG(total_score) FOR city IN ([London],[Liverpool],[Leeds],[Manchester]) ) AS StudentPivotTable
Catatan: Untuk membuat database dan data dummy, lihat artikel sebelumnya tentang Operator Pivot.
Batasan Operator Pivot
Namun, ada batasan tertentu dari operator pivot. Di dalam operator pivot, kita harus menentukan bidang agregat dan kolom yang ingin kita pivotkan datanya. Terakhir, kita juga harus menetapkan nilai individual untuk judul kolom yang ingin kita buat.
Jika kita mengeksekusi script dari bagian sebelumnya, kita akan mendapatkan hasil sebagai berikut:
[id tabel=35 /]
Judul kolom adalah nilai individual di dalam kolom kota. Kami menetapkan nilai-nilai ini di dalam operator pivot dalam kueri kami.
Bagian paling membosankan dalam membuat tabel pivot adalah menentukan nilai untuk judul kolom secara manual. Ini adalah bagian yang paling rentan terhadap kesalahan, terutama jika data di sumber data online Anda berubah. Kami tidak dapat memastikan bahwa nilai yang kami tentukan di operator pivot akan tetap ada di database sampai kami membuat tabel pivot ini di lain waktu.
Misalnya, dalam skrip kami, kami menetapkan London, Liverpool, Leeds, dan Manchester sebagai nilai untuk judul tabel pivot kami. Nilai-nilai ini ada di kolom ity dari tabel siswa. Bagaimana jika satu atau lebih dari nilai-nilai ini dihapus atau diperbarui? Dalam kasus seperti itu, null akan dikembalikan.
Pendekatan yang lebih baik adalah membuat kueri dinamis yang akan mengembalikan kumpulan nilai lengkap dari kolom tempat Anda mencoba membuat tabel pivot.
Membuat Tabel Pivot Dinamis
Di bagian ini, kita akan melihat cara membuat tabel pivot dinamis.
Ini berarti bahwa kita tidak perlu secara manual menentukan nilai untuk kolom dari mana kita mencoba untuk menghasilkan tabel pivot kita. Sebagai gantinya, kami akan menetapkan nilai-nilai ini secara dinamis. Untuk tujuan ini, kita akan menggunakan fungsi “QUOTENAME”.
Seperti biasa, pastikan Anda didukung dengan baik sebelum bereksperimen dengan kode baru. Lihat artikel ini tentang mencadangkan database MS SQL jika Anda tidak yakin.
Fungsi QUOTENAME
Fungsi “QUOTENAME” memformat hasil yang dipilih. Sebelum menjelaskan pivot dinamis, ada baiknya melihat contoh kerja cepat dari fungsi “QUOTENAME”.
Perhatikan kueri berikut.
USE schooldb SELECT QUOTENAME(city)+ ',' FROM student
Secara default, fungsi “QUOTENAME” membungkus item yang dipilih dengan tanda kurung siku. Output dari query di atas terlihat seperti ini:
[id tabel=36 /]
Menyimpan Nama Kolom dalam Variabel
Meskipun kita telah membungkus nilai kolom dengan tanda kurung siku, kita perlu menentukan nilai dalam operator pivot dalam format ini:
“[Leeds],[Liverpool],[London],[Manchester]”
Untuk melakukan ini, kita membutuhkan sebuah variabel.
USE schooldb DECLARE @CityNames NVARCHAR(MAX) = '' SELECT @CityNames += QUOTENAME(city)+ ',' FROM ( SELECT DISTINCT city FROM student ) AS CITIES PRINT @CityNames
Dalam kueri di atas, kami mendeklarasikan variabel “@CityNames” dan menginisialisasinya dengan string kosong. Kemudian, kami menggunakan pernyataan SELECT untuk memilih nama kota yang berbeda dari kolom kota dan menyimpannya secara iteratif dalam variabel “@CityNames”. Di setiap iterasi, nilai yang berbeda di kolom kota bersama dengan koma akan ditambahkan ke variabel “@CityNames”.
Kemudian, kami mencetak nilai yang disimpan dalam variabel ini. Hasil query di atas akan terlihat seperti ini:
“[Leeds],[Liverpool],[London],[Manchester],”
Jika Anda melihat output, ada koma setelah nilai terakhir. Kami tidak membutuhkan itu.
Menghapus Tanda Koma
Untuk menghapus tanda koma, kita akan menggunakan fungsi LEFT yang menggunakan string sebagai argumen pertamanya. Argumen kedua adalah jumlah karakter yang akan dikembalikan dari string itu mulai dari karakter pertama. Perhatikan kueri berikut:
USE schooldb DECLARE @CityNames NVARCHAR(MAX) = '' SELECT @CityNames += QUOTENAME(city)+ ',' FROM ( SELECT DISTINCT city FROM student ) AS CITIES SET @CityNames = LEFT(@CityNames, LEN(@CityNames)-1) PRINT @CityNames
Di sini perhatikan baris skrip ini:
SET @CityNames = LEFT(@CityNames, LEN(@CityNames)-1)
Di baris skrip ini, kami menggunakan fungsi LEFT untuk mendapatkan semua karakter di sisi kiri nilai yang disimpan dalam variabel “@CityNames”, mulai dari elemen pertama. Dalam argumen kedua, kami menggunakan fungsi LEN untuk menghitung jumlah elemen nilai yang disimpan dalam fungsi “@CityNames” dan akhirnya, kami mengurangi 1 darinya. Ini menghilangkan tanda koma dari string. Outputnya akan terlihat seperti ini:
[Leeds],[Liverpool],[London],[Manchester]
Mengonversi Kueri SQL ke String
Sekarang, mudah-mudahan, kita bisa menggunakan variabel “@CityNames” di dalam operator pivot kita seperti ini:
PIVOT( AVG(total_score) FOR city IN ( @CityNames )
Namun, kami tidak dapat menggunakan variabel di dalam operator pivot kami. Pendekatan alternatifnya adalah mengonversi kueri SQL lengkap kami menjadi string. Di dalam string ini, kita akan mengaitkan variabel “@CityNames” kita.
USE schooldb DECLARE @CityNames NVARCHAR(MAX) = '' DECLARE @Query NVARCHAR(MAX) = '' SELECT @CityNames += QUOTENAME(city)+ ',' FROM ( SELECT DISTINCT city FROM student ) AS CITIES SET @CityNames = LEFT(@CityNames, LEN(@CityNames)-1) SET @Query = 'SELECT * FROM (SELECT city, total_score FROM student ) AS StudentTable PIVOT( AVG(total_score) FOR city IN (' + @CityNames +') ) AS StudentPivotTable' PRINT @Query
Di sini kami mendeklarasikan variabel "@Query" dan menyimpan kueri SQL kami di variabel ini. Di dalam operator pivot, kami menggabungkan nilai yang disimpan di dalam variabel “@CityNames”. Untuk melihat tampilan kueri yang dieksekusi, kami telah mencetak nilai variabel “@Query”. Kueri yang dihasilkan akan terlihat seperti ini di output:
SELECT * FROM (SELECT city, total_score FROM student ) AS StudentTable PIVOT( AVG(total_score) FOR city IN ([Leeds],[Liverpool],[London],[Manchester]) ) AS StudentPivotTable
Ini persis jenis kueri yang ingin kita jalankan. Namun, ini dalam format String. Langkah terakhir adalah menjalankan kueri SQL yang disimpan sebagai string teks. Untuk melakukan ini, kita akan menggunakan SQL Dinamis.
Menjalankan SQL Dinamis
Kami menggunakan prosedur bawaan "sp_executesql" untuk mengeksekusi SQL dinamis. Kami akan menggunakan prosedur tersimpan ini untuk menjalankan kueri yang disimpan dalam variabel @Query. Kueri terakhir kami yang membuat tabel pivot dinamis terlihat seperti ini:
USE schooldb DECLARE @CityNames NVARCHAR(MAX) = '' DECLARE @Query NVARCHAR(MAX) = '' SELECT @CityNames += QUOTENAME(city)+ ',' FROM ( SELECT DISTINCT city FROM student ) AS CITIES SET @CityNames = LEFT(@CityNames, LEN(@CityNames)-1) SET @Query = 'SELECT * FROM (SELECT city, total_score FROM student ) AS StudentTable PIVOT( AVG(total_score) FOR city IN (' + @CityNames +') ) AS StudentPivotTable' EXECUTE sp_executesql @Query
Saat Anda menjalankan kueri di atas, Anda akan melihat hasil berikut:
[id tabel=37 /]
Namun, kali ini, kami tidak secara manual menentukan nilai untuk judul tabel pivot. Sebaliknya, judul telah dihitung secara dinamis yang menghasilkan tabel pivot dinamis.