Saya mencoba mencari posting, tetapi saya hanya menemukan solusi untuk SQL Server / Access. Saya butuh solusi di MySQL (5.X).
Saya punya tabel (disebut histori) dengan 3 kolom: hostid, itemname, itemvalue.
Jika saya melakukan select ( select * from history
), itu akan kembali
+--------+----------+-----------+
| hostid | itemname | itemvalue |
+--------+----------+-----------+
| 1 | A | 10 |
+--------+----------+-----------+
| 1 | B | 3 |
+--------+----------+-----------+
| 2 | A | 9 |
+--------+----------+-----------+
| 2 | c | 40 |
+--------+----------+-----------+
Bagaimana saya meminta basis data untuk mengembalikan sesuatu seperti
+--------+------+-----+-----+
| hostid | A | B | C |
+--------+------+-----+-----+
| 1 | 10 | 3 | 0 |
+--------+------+-----+-----+
| 2 | 9 | 0 | 40 |
+--------+------+-----+-----+
Jawaban:
Saya akan menambahkan penjelasan yang agak lebih panjang dan lebih rinci tentang langkah yang harus diambil untuk menyelesaikan masalah ini. Saya minta maaf jika terlalu lama.
Saya akan mulai dengan pangkalan yang Anda berikan dan menggunakannya untuk menentukan beberapa istilah yang akan saya gunakan untuk sisa posting ini. Ini akan menjadi tabel dasar :
Ini akan menjadi tujuan kami, tabel pivot cantik :
Nilai dalam
history.hostid
kolom akan menjadi nilai-y dalam tabel pivot. Nilai dalamhistory.itemname
kolom akan menjadi nilai x (untuk alasan yang jelas).Ketika saya harus menyelesaikan masalah membuat tabel pivot, saya mengatasinya menggunakan proses tiga langkah (dengan langkah keempat opsional):
Mari kita terapkan langkah-langkah ini untuk masalah Anda dan lihat apa yang kami dapatkan:
Langkah 1: pilih kolom yang diminati . Dalam hasil yang diinginkan,
hostid
menyediakan y-nilai danitemname
menyediakan x-nilai .Langkah 2: perpanjang tabel dasar dengan kolom tambahan . Kami biasanya membutuhkan satu kolom per nilai x. Ingat bahwa kolom x-value kami adalah
itemname
:Perhatikan bahwa kami tidak mengubah jumlah baris - kami baru saja menambahkan kolom tambahan. Perhatikan juga pola
NULL
s - baris denganitemname = "A"
nilai bukan nol untuk kolom baruA
, dan nilai nol untuk kolom baru lainnya.Langkah 3: kelompokkan dan agregat tabel diperpanjang . Kita perlu
group by hostid
, karena memberikan nilai-y:(Perhatikan bahwa kita sekarang memiliki satu baris per nilai-y.) Oke, kita hampir sampai! Kita hanya perlu menyingkirkan yang jelek
NULL
itu.Langkah 4: cantikkan . Kami hanya akan mengganti nilai nol dengan nol sehingga set hasil lebih baik untuk dilihat:
Dan kami selesai - kami telah membangun tabel pivot yang bagus dan cantik menggunakan MySQL.
Pertimbangan saat menerapkan prosedur ini:
itemvalue
contoh iniNULL
, tetapi bisa juga0
atau""
, tergantung pada situasi Anda yang sebenarnyasum
, tetapicount
danmax
juga sering digunakan (max
sering digunakan ketika membangun "objek" satu baris yang telah tersebar di banyak baris)group by
klausa (dan jangan lupa untukselect
itu)Keterbatasan yang diketahui:
sumber
sumber
group by
.MAX
bukanSUM
karenaitemValue
string saya , bukan nilai numerik.Opsi lain, terutama berguna jika Anda memiliki banyak item yang perlu Anda pivot adalah membiarkan mysql membuat kueri untuk Anda:
FIDDLE Menambahkan beberapa nilai tambahan agar berfungsi
GROUP_CONCAT
memiliki nilai default 1000 jadi jika Anda memiliki kueri yang sangat besar ubah parameter ini sebelum menjalankannyaUji:
sumber
'ifnull(SUM(case when itemname = ''',
dengan''' then itemvalue end),0) AS
', `untuk'SUM(case when itemname = '''
dengan''' then itemvalue else 0 end) AS ',
. Ini menghasilkan istilah sepertiSUM(case when itemname = 'A' then itemvalue else 0 end) AS 'A'
.Mengambil keuntungan dari ide Matt Fenwick yang membantu saya untuk menyelesaikan masalah (terima kasih banyak), mari kita kurangi menjadi hanya satu permintaan:
sumber
Saya mengedit jawaban Agung Sagita dari subquery untuk bergabung. Saya tidak yakin tentang seberapa besar perbedaan antara 2 cara ini, tetapi hanya untuk referensi lain.
sumber
gunakan subquery
tetapi akan menjadi masalah jika sub kueri menghasilkan lebih dari satu baris, gunakan fungsi agregat lebih lanjut dalam subquery
sumber
Solusi saya:
Ini menghasilkan hasil yang diharapkan dalam kasus yang diajukan.
sumber
Saya membuatnya menjadi
Group By hostId
maka hanya akan menampilkan baris pertama dengan nilai-nilai,seperti:
sumber
Saya menemukan satu cara untuk membuat laporan saya mengonversi baris ke kolom hampir dinamis menggunakan kueri sederhana. Anda dapat melihat dan mengujinya secara online di sini .
Jumlah kolom kueri tetap tetapi nilainya dinamis dan didasarkan pada nilai baris. Anda dapat membangunnya Jadi, saya menggunakan satu kueri untuk membangun tajuk tabel dan yang lainnya untuk melihat nilainya:
Anda juga dapat meringkasnya:
Hasil RexTester :
http://rextester.com/ZSWKS28923
Untuk satu contoh nyata penggunaan, laporan ini di bawah menunjukkan dalam kolom jam keberangkatan kedatangan kapal / bus dengan jadwal visual. Anda akan melihat satu kolom tambahan yang tidak digunakan pada kolom terakhir tanpa membingungkan visualisasi: ** sistem tiket untuk penjualan tiket online dan presentasi
sumber
Jika Anda bisa menggunakan MariaDB ada solusi yang sangat sangat mudah.
Sejak MariaDB-10.02 telah ditambahkan mesin penyimpanan baru bernama CONNECT yang dapat membantu kami mengubah hasil kueri atau tabel lain menjadi tabel pivot, seperti yang Anda inginkan: Anda dapat melihat dokumen .
Pertama-tama instal mesin penyambung koneksi .
Sekarang kolom pivot dari tabel kami adalah
itemname
dan data untuk setiap item terletak diitemvalue
kolom, sehingga kami dapat memiliki tabel pivot hasil menggunakan kueri ini:Sekarang kita dapat memilih apa yang kita inginkan dari
pivot_table
:Lebih detail di sini
sumber
Ini bukan jawaban yang tepat yang Anda cari tetapi itu adalah solusi yang saya butuhkan pada proyek saya dan berharap ini membantu seseorang. Ini akan mencantumkan 1 hingga n item baris yang dipisahkan oleh koma. Group_Compat memungkinkan ini di MySQL.
Kuburan ini memiliki dua nama umum sehingga nama-nama tersebut terdaftar dalam baris yang berbeda yang terhubung oleh satu id tetapi dua id nama dan permintaan menghasilkan sesuatu seperti
CemeteryIDame_Name Latitude
1 Appleton ini, Sulpher Springs 35.4276242832293
sumber
Saya minta maaf untuk mengatakan ini dan mungkin saya tidak memecahkan masalah Anda persis tetapi PostgreSQL 10 tahun lebih tua dari MySQL dan sangat maju dibandingkan dengan MySQL dan ada banyak cara untuk mencapai ini dengan mudah. Instal PostgreSQL dan jalankan kueri ini
lalu voila! Dan inilah dokumentasi yang lengkap: PostgreSQL: Dokumentasi: 9.1: tablefunc atau permintaan ini
sekali lagi voila! PostgreSQL: Dokumentasi: 9.0: hstore
sumber