Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Permintaan mysql untuk secara dinamis mengonversi baris ke kolom berdasarkan dua kolom

Jika Anda memiliki jumlah nilai yang diketahui untuk kedua order dan item , maka Anda dapat membuat kode kueri menjadi:

select id,
  max(case when `order` = 1 then data end) order1,
  max(case when `order` = 2 then data end) order2,
  max(case when `order` = 3 then data end) order3,
  max(case when item = 1 then price end) item1,
  max(case when item = 2 then price end) item2,
  max(case when item = 3 then price end) item3,
  max(case when item = 4 then price end) item4
from tableA
group by id;

Lihat Demo . Tetapi bagian dari masalah yang akan Anda hadapi adalah karena Anda mencoba mengubah beberapa kolom data. Saran saya untuk mendapatkan hasil akhir adalah unpivot data terlebih dahulu. MySQL tidak memiliki fungsi unpivot tetapi Anda dapat menggunakan UNION ALL untuk mengubah beberapa pasang kolom menjadi baris. Kode unpivot akan mirip dengan berikut ini:

select id, concat('order', `order`) col,  data value
from tableA
union all
select id, concat('item', item) col, price value
from tableA;

Lihat Demo . Hasilnya adalah:

| ID |    COL | VALUE |
-----------------------
|  1 | order1 |     P |
|  1 | order1 |     P |
|  1 | order1 |     P |
|  1 |  item1 |    50 |
|  1 |  item2 |    60 |
|  1 |  item3 |    70 |

Seperti yang Anda lihat, ini telah mengambil beberapa kolom order /data dan item /price dan mengubahnya menjadi beberapa baris. Setelah selesai, Anda dapat mengonversi nilai kembali menjadi kolom menggunakan fungsi agregat dengan CASE:

select id, 
  max(case when col = 'order1' then value end) order1,
  max(case when col = 'order2' then value end) order2,
  max(case when col = 'order3' then value end) order3,
  max(case when col = 'item1' then value end) item1,
  max(case when col = 'item2' then value end) item2,
  max(case when col = 'item3' then value end) item3
from
(
  select id, concat('order', `order`) col,  data value
  from tableA
  union all
  select id, concat('item', item) col, price value
  from tableA
) d
group by id;

Lihat Demo . Terakhir, Anda perlu mengonversi kode di atas menjadi kueri pernyataan dinamis yang disiapkan:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when col = ''',
      col,
      ''' then value end) as `', 
      col, '`')
  ) INTO @sql
FROM
(
  select concat('order', `order`) col
  from tableA
  union all
  select concat('item', `item`) col
  from tableA
)d;

SET @sql = CONCAT('SELECT id, ', @sql, ' 
                  from
                  (
                    select id, concat(''order'', `order`) col,  data value
                    from tableA
                    union all
                    select id, concat(''item'', item) col, price value
                    from tableA
                  ) d
                  group by id');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Lihat SQL Fiddle dengan demo . Ini memberikan hasil:

| ID | ORDER1 | ORDER2 | ORDER3 | ITEM1 | ITEM2 |  ITEM3 |  ITEM4 |
-------------------------------------------------------------------
|  1 |      P |      Q | (null) |    50 |    60 |     70 | (null) |
|  2 |      P | (null) |      S |    50 |    60 | (null) |     80 |



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Menjalankan Galera Cluster di Kubernetes

  2. Cara menghitung item dalam daftar yang dipisahkan koma MySQL

  3. Kelola MySQL dengan phpMyAdmin di Ubuntu 9.10 (Karmic)

  4. Memigrasikan MySQL ke PostgreSQL di AWS RDS, Bagian 2

  5. Memotong semua tabel dalam database MySQL dalam satu perintah?