Saya telah diberi tugas untuk menerjemahkan data berikut:
date category amount
1/1/2012 ABC 1000.00
2/1/2012 DEF 500.00
2/1/2012 GHI 800.00
2/10/2012 DEF 700.00
3/1/2012 ABC 1100.00
menjadi sebagai berikut:
date ABC DEF GHI
1/1/2012 1000.00
2/1/2012 500.00
2/1/2012 800.00
2/10/2012 700.00
3/1/2012 1100.00
Bintik kosong dapat berupa NULL atau kosong, baik-baik saja, dan kategorinya harus dinamis. Peringatan lain yang mungkin untuk ini adalah bahwa kami akan menjalankan kueri dalam kapasitas terbatas, yang berarti tabel temp tidak tersedia. Saya sudah mencoba untuk meneliti dan telah mendarat PIVOT
tetapi karena saya belum pernah menggunakannya sebelumnya saya benar-benar tidak memahaminya, meskipun upaya terbaik saya untuk mengetahuinya. Adakah yang bisa mengarahkan saya ke arah yang benar?
sql
sql-server
tsql
pivot
Sean Cunningham
sumber
sumber
Jawaban:
PIVOT SQL dinamis:
Hasil:
sumber
@cols
maka Anda dapat menghapusDISTINCT
dan menggunakanGROUP BY
danORDER BY
ketika Anda mendapatkan daftar@cols
.PIVOT SQL dinamis
Pendekatan berbeda untuk membuat string kolom
Hasil
sumber
Saya tahu pertanyaan ini lebih lama tetapi saya mencari jawaban dan berpikir bahwa saya mungkin dapat memperluas bagian "dinamis" dari masalah dan mungkin membantu seseorang.
Pertama dan terpenting saya membangun solusi ini untuk memecahkan masalah yang dialami oleh beberapa rekan kerja dengan set data yang tidak konstan dan besar yang perlu diputar cepat.
Solusi ini memerlukan pembuatan prosedur tersimpan sehingga jika itu tidak sesuai dengan kebutuhan Anda, silakan berhenti membaca sekarang.
Prosedur ini akan mengambil variabel kunci dari pernyataan pivot untuk secara dinamis membuat pernyataan pivot untuk berbagai tabel, nama kolom, dan agregat. Kolom statis digunakan sebagai grup oleh / kolom identitas untuk pivot (ini dapat dihapus dari kode jika tidak diperlukan tetapi cukup umum dalam pernyataan pivot dan diperlukan untuk menyelesaikan masalah asli), kolom pivot adalah tempat nama kolom hasil akhir akan dihasilkan dari, dan kolom nilai adalah apa yang akan diterapkan pada agregat. Parameter Tabel adalah nama tabel termasuk skema (schema.tablename), bagian kode ini dapat menggunakan beberapa cinta karena tidak sebersih yang saya inginkan. Ini bekerja untuk saya karena penggunaan saya tidak menghadap ke publik dan injeksi sql bukan masalah.
Mari kita mulai dengan kode untuk membuat prosedur tersimpan. Kode ini harus bekerja di semua versi SSMS 2005 dan di atas tetapi saya belum mengujinya pada 2005 atau 2016 tetapi saya tidak bisa melihat mengapa itu tidak berhasil.
Selanjutnya kita akan mendapatkan data kita siap untuk contoh. Saya telah mengambil contoh data dari jawaban yang diterima dengan penambahan beberapa elemen data untuk digunakan dalam bukti konsep ini untuk menunjukkan hasil yang bervariasi dari perubahan agregat.
Contoh-contoh berikut menunjukkan pernyataan eksekusi bervariasi yang menunjukkan agregat bervariasi sebagai contoh sederhana. Saya tidak memilih untuk mengubah kolom statis, pivot, dan nilai untuk menjaga contoh sederhana. Anda dapat menyalin dan menempelkan kode untuk mulai mengacaukannya sendiri
Eksekusi ini mengembalikan set data berikut masing-masing.
sumber
Versi terbaru untuk SQL Server 2017 menggunakan fungsi STRING_AGG untuk membuat daftar kolom pivot:
sumber
Anda dapat mencapai ini menggunakan TSQL dinamis (ingat untuk menggunakan QUOTENAME untuk menghindari serangan injeksi SQL):
Pivot dengan Kolom Dinamis di SQL Server 2005
SQL Server - Tabel PIVOT Dinamis - SQL Injection
Referensi wajib untuk Kutukan dan Berkat dari Dynamic SQL
sumber
QUOTENAME
hanya membantu serangan injeksi SQL jika Anda menerima @tableName sebagai parameter dari pengguna, dan menambahkannya ke kueri sepertiSET @sql = 'SELECT * FROM ' + @tableName;
. Anda dapat membangun banyak string SQL dinamis yang rentan danQUOTENAME
tidak akan melakukan apa pun untuk membantu Anda.Ada solusi saya membersihkan nilai nol yang tidak perlu
sumber
Kode di bawah ini memberikan hasil yang menggantikan NULL ke nol dalam output.
Pembuatan tabel dan penyisipan data:
Kueri untuk menghasilkan hasil yang tepat yang juga menggantikan NULL dengan nol:
OUTPUT:
sumber