Bagaimana cara mengganti kolom dengan baris di SQL? Apakah ada perintah sederhana untuk mengubah urutan?
yaitu putar hasil ini:
Paul | John | Tim | Eric
Red 1 5 1 3
Green 8 4 3 5
Blue 2 2 9 1
ke dalam ini:
Red | Green | Blue
Paul 1 8 2
John 5 4 2
Tim 1 3 9
Eric 3 5 1
PIVOT
tampaknya terlalu rumit untuk skenario ini.
sql
sql-server
tsql
pivot
edezzie.dll
sumber
sumber
Jawaban:
Ada beberapa cara untuk mengubah data ini. Di posting asli Anda, Anda menyatakan bahwa
PIVOT
tampaknya terlalu rumit untuk skenario ini, tetapi dapat diterapkan dengan sangat mudah menggunakan fungsiUNPIVOT
danPIVOT
di SQL Server.Namun, jika Anda tidak memiliki akses ke fungsi tersebut, ini dapat direplikasi menggunakan
UNION ALL
keUNPIVOT
dan kemudian fungsi agregat denganCASE
pernyataan kePIVOT
:Buat tabel:
Union All, Agregat dan Versi CASE:
Lihat SQL Fiddle dengan Demo
Itu
UNION ALL
melakukanUNPIVOT
data dengan mengubah kolomPaul, John, Tim, Eric
menjadi baris terpisah. Kemudian Anda menerapkan fungsi agregatsum()
dengancase
pernyataan tersebut untuk mendapatkan kolom baru untuk masing-masingcolor
.Versi Statis Unpivot dan Pivot:
Baik fungsi
UNPIVOT
danPIVOT
di server SQL membuat transformasi ini jauh lebih mudah. Jika Anda mengetahui semua nilai yang ingin diubah, Anda dapat melakukan hard-code pada nilai tersebut menjadi versi statis untuk mendapatkan hasilnya:Lihat SQL Fiddle dengan Demo
Kueri dalam dengan
UNPIVOT
menjalankan fungsi yang sama sepertiUNION ALL
. Ini mengambil daftar kolom dan mengubahnya menjadi baris,PIVOT
kemudian melakukan transformasi terakhir menjadi kolom.Versi Pivot Dinamis:
Jika Anda memiliki jumlah kolom yang tidak diketahui (
Paul, John, Tim, Eric
dalam contoh Anda) dan kemudian jumlah warna yang tidak diketahui untuk diubah, Anda dapat menggunakan sql dinamis untuk membuat daftarUNPIVOT
dan kemudianPIVOT
:Lihat SQL Fiddle dengan Demo
Kueri versi dinamis keduanya
yourtable
dan kemudiansys.columns
tabel untuk menghasilkan daftar item keUNPIVOT
danPIVOT
. Ini kemudian ditambahkan ke string kueri untuk dieksekusi. Kelebihan dari versi dinamis adalah jika Anda memiliki daftar yang berubahcolors
dan / ataunames
ini akan menghasilkan daftar pada saat run-time.Ketiga kueri tersebut akan menghasilkan hasil yang sama:
sumber
Ini biasanya mengharuskan Anda untuk mengetahui SEMUA label kolom DAN baris sebelumnya. Seperti yang Anda lihat dalam kueri di bawah ini, semua label terdaftar seluruhnya di operasi UNPIVOT dan (ulang) PIVOT.
Penataan Skema MS SQL Server 2012 :
Pertanyaan 1 :
Hasil :
Catatan tambahan:
sumber
Saya ingin menunjukkan beberapa solusi lagi untuk mengubah urutan kolom dan baris dalam SQL.
Yang pertama adalah - menggunakan CURSOR. Meskipun konsensus umum dalam komunitas profesional adalah menjauh dari SQL Server Cursor, masih ada contoh di mana penggunaan kursor direkomendasikan. Bagaimanapun, Cursor memberi kita opsi lain untuk mengubah urutan baris menjadi kolom.
Ekspansi vertikal
Mirip dengan PIVOT, kursor memiliki kemampuan dinamis untuk menambahkan lebih banyak baris saat kumpulan data Anda meluas untuk menyertakan lebih banyak nomor kebijakan.
Ekspansi horizontal
Berbeda dengan PIVOT, kursor unggul di area ini karena dapat diperluas untuk menyertakan dokumen yang baru ditambahkan, tanpa mengubah skrip.
Rincian kinerja
Batasan utama dalam mentransposisi baris menjadi kolom menggunakan CURSOR adalah kerugian yang terkait dengan penggunaan kursor secara umum - biaya kinerja yang signifikan. Ini karena Cursor menghasilkan kueri terpisah untuk setiap operasi FETCH NEXT.
Solusi lain untuk mengubah baris menjadi kolom adalah dengan menggunakan XML.
Solusi XML untuk mengubah baris menjadi kolom pada dasarnya adalah versi optimal dari PIVOT karena mengatasi batasan kolom dinamis.
Versi XML dari skrip mengatasi batasan ini dengan menggunakan kombinasi XML Path, T-SQL dinamis dan beberapa fungsi built-in (yaitu STUFF, QUOTENAME).
Ekspansi vertikal
Mirip dengan PIVOT dan Cursor, kebijakan yang baru ditambahkan dapat diambil dalam versi XML dari skrip tanpa mengubah skrip asli.
Ekspansi horizontal
Berbeda dengan PIVOT, dokumen yang baru ditambahkan dapat ditampilkan tanpa mengubah skrip.
Rincian kinerja
Dalam hal IO, statistik skrip versi XML hampir mirip dengan PIVOT - satu-satunya perbedaan adalah XML memiliki pemindaian kedua dari tabel dtTranspose tetapi kali ini dari cache data-baca yang logis.
Anda dapat menemukan lebih banyak lagi tentang solusi ini (termasuk beberapa contoh T-SQL aktual) di artikel ini: https://www.sqlshack.com/multiple-options-to-transposing-rows-into-columns/
sumber
Berdasarkan solusi dari bluefeet berikut ini adalah prosedur tersimpan yang menggunakan sql dinamis untuk menghasilkan tabel yang dialihkan. Ini mensyaratkan bahwa semua bidang adalah numerik kecuali untuk kolom yang dialihkan (kolom yang akan menjadi tajuk dalam tabel yang dihasilkan):
Anda dapat mengujinya dengan tabel yang disediakan dengan perintah ini:
sumber
Saya lakukan
UnPivot
pertama kali dan menyimpan hasil dalamCTE
dan menggunakanCTE
dalamPivot
operasi.Demo
sumber
Menambahkan jawaban hebat @Paco Zarate di atas, jika Anda ingin mengubah urutan tabel yang memiliki beberapa jenis kolom, tambahkan ini ke akhir baris 39, sehingga hanya mengubah posisi
int
kolom:Berikut adalah kueri lengkap yang sedang diubah:
Untuk menemukan yang lain
system_type_id
, jalankan ini:sumber
Saya ingin membagikan kode yang saya gunakan untuk mengubah urutan teks yang dipisahkan berdasarkan jawaban + bluefeet. Dalam pendekatan ini saya diimplementasikan sebagai prosedur di MS SQL 2005
Saya mencampur solusi ini dengan informasi tentang cara memesan baris tanpa urutan oleh ( SQLAuthority.com ) dan fungsi pemisahan di MSDN ( social.msdn.microsoft.com )
Saat Anda menjalankan produk
Anda mendapatkan hasil selanjutnya
sumber
Dengan cara ini Mengkonversi semua Data Dari Filelds (Kolom) Dalam Tabel Untuk Merekam (Baris).
sumber
Saya dapat menggunakan solusi Paco Zarate dan itu bekerja dengan baik. Saya memang harus menambahkan satu baris ("SET ANSI_WARNINGS ON"), tetapi itu mungkin sesuatu yang unik untuk cara saya menggunakannya atau menyebutnya. Ada masalah dengan penggunaan saya dan saya harap seseorang dapat membantu saya:
Solusinya hanya berfungsi dengan tabel SQL yang sebenarnya. Saya mencobanya dengan tabel sementara dan juga tabel dalam memori (dideklarasikan) tetapi tidak berhasil dengan tabel tersebut. Jadi dalam kode panggilan saya, saya membuat tabel di database SQL saya dan kemudian memanggil SQLTranspose. Sekali lagi, ini bekerja dengan baik. Itu yang saya inginkan. Inilah masalah saya:
Agar solusi keseluruhan menjadi benar-benar dinamis, saya perlu membuat tabel itu di mana saya menyimpan sementara informasi yang telah disiapkan yang saya kirim ke SQLTranspose "dengan cepat", dan kemudian menghapus tabel itu setelah SQLTranspose dipanggil. Penghapusan tabel menimbulkan masalah dengan rencana implementasi akhir saya. Kode harus dijalankan dari aplikasi pengguna akhir (tombol pada formulir / menu Microsoft Access). Ketika saya menggunakan proses SQL ini (membuat tabel SQL, panggil SQLTranspose, hapus tabel SQL) aplikasi pengguna akhir mengalami kesalahan karena akun SQL yang digunakan tidak memiliki hak untuk menjatuhkan tabel.
Jadi saya pikir ada beberapa kemungkinan solusi:
Temukan cara untuk membuat SQLTranspose berfungsi dengan tabel sementara atau variabel tabel yang dideklarasikan.
Cari tahu metode lain untuk transposisi baris dan kolom yang tidak memerlukan tabel SQL yang sebenarnya.
Cari tahu metode yang sesuai untuk mengizinkan akun SQL yang digunakan oleh pengguna akhir saya untuk menghapus tabel. Ini adalah satu akun SQL bersama yang dikodekan ke dalam aplikasi Access saya. Tampaknya izin adalah hak istimewa tipe dbo yang tidak dapat diberikan.
Saya menyadari bahwa beberapa di antaranya mungkin memerlukan utas dan pertanyaan lain yang terpisah. Namun, karena ada kemungkinan bahwa satu solusi mungkin hanyalah cara yang berbeda untuk melakukan pengalihan baris dan kolom, saya akan membuat posting pertama saya di sini di utas ini.
EDIT: Saya juga mengganti jumlah (nilai) dengan max (nilai) di baris ke-6 dari akhir, seperti yang disarankan Paco.
EDIT:
Saya menemukan sesuatu yang berhasil untuk saya. Saya tidak tahu apakah itu jawaban terbaik atau bukan.
Saya memiliki akun pengguna hanya-baca yang digunakan untuk menjalankan prosedur terstruktur dan oleh karena itu menghasilkan keluaran pelaporan dari database. Karena fungsi SQLTranspose yang saya buat hanya akan bekerja dengan tabel "sah" (bukan tabel yang dideklarasikan dan bukan tabel sementara) saya harus mencari cara untuk akun pengguna hanya-baca untuk membuat (dan kemudian menghapus) tabel .
Saya beralasan bahwa untuk tujuan saya, tidak masalah bagi akun pengguna untuk diizinkan membuat tabel. Namun, pengguna tetap tidak dapat menghapus tabel. Solusi saya adalah membuat skema di mana akun pengguna diotorisasi. Kemudian setiap kali saya membuat, menggunakan, atau menghapus tabel itu, referensikan dengan skema yang ditentukan.
Saya pertama kali mengeluarkan perintah ini dari akun 'sa' atau 'sysadmin': CREATE SCHEMA ro AUTHORIZATION
Kapan pun saya merujuk ke tabel "tmpoutput" saya, saya menetapkannya seperti contoh ini:
drop tabel ro.tmpoutput
sumber