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

Pilih baris MYSQL tetapi baris menjadi kolom dan kolom menjadi baris

Dengan kolom tetap dan diketahui, inilah cara melakukannya (saya mengambil kebebasan untuk menamai tabel "nilai"):

Ide Umum:

Untuk membuat gabungan kueri yang berbeda dan menjalankannya.

Karena Anda memerlukan data aktual sebagai tajuk kolom, bagian pertama dari gabungan akan terlihat seperti:

SELECT 'id', '1', '2', ....

Permintaan itu sendiri akan menduplikasi hasilnya, oleh karena itu kita perlu memberi tahu MySQL bahwa kita harus memiliki 0 baris dengan menambahkan LIMIT 0, 0 .

Baris pertama serikat kami akan berisi 'Name' , serta semua data dari kolom "Nama" tabel. Untuk mendapatkan baris itu kita membutuhkan query seperti:

SELECT 'Name',
    (SELECT Name FROM grades LIMIT 0, 1),
    (SELECT Name FROM grades LIMIT 1, 1),
    (SELECT Name FROM grades LIMIT 2, 1),
    ...

Menggunakan logika yang sama, baris kedua kita akan terlihat seperti:

SELECT 'Marks',
    (SELECT Marks FROM grades LIMIT 0, 1),
    (SELECT Marks FROM grades LIMIT 1, 1),
    (SELECT Marks FROM grades LIMIT 2, 1),
    ...

Mendapatkan tajuk:

Kita perlu membuat baris dari MySQL seperti:

SELECT 'id', '1', '2', ... LIMIT 0, 0;

Untuk mendapatkan baris itu kita akan menggunakan CONCAT() dan GROUP_CONCAT() fungsi:

SELECT 'id', 
    (SELECT GROUP_CONCAT(CONCAT(' \'', id, '\'')) FROM grades)
LIMIT 0, 0;

dan kita akan menyimpan baris itu ke dalam variabel baru:

SET @header = CONCAT('SELECT \'id\', ',
    (SELECT GROUP_CONCAT(CONCAT(' \'', id, '\'')) FROM grades),
    ' LIMIT 0, 0');

Membuat garis:

Kita perlu membuat dua query seperti berikut:

SELECT 'Name',
    (SELECT Name FROM grades LIMIT 0, 1),
    (SELECT Name FROM grades LIMIT 1, 1),
    (SELECT Name FROM grades LIMIT 2, 1),
    ...

Karena kita tidak tahu sebelumnya berapa banyak baris yang ada di tabel asli kita, kita akan menggunakan variabel untuk menghasilkan LIMIT x, 1 yang berbeda pernyataan. Mereka dapat diproduksi menggunakan yang berikut:

SET @a = -1;
SELECT @a:[email protected]+1 FROM grades;

Dengan menggunakan cuplikan ini, kita dapat membuat subkueri:

SELECT GROUP_CONCAT(
    CONCAT(' (SELECT name FROM grades LIMIT ',
        @a:[email protected]+1,
        ', 1)')
    )
FROM grades

Yang akan kita masukkan ke dalam nama variabel @line1, beserta data kolom pertama (yang merupakan nama kolom kedua):

SET @a = -1;
SET @line1 = CONCAT(
    'SELECT \'Name\',',
    (
        SELECT GROUP_CONCAT(
            CONCAT(' (SELECT Name FROM grades LIMIT ',
                @a:[email protected]+1,
                ', 1)')
            )
        FROM grades
    ));

Dengan mengikuti logika yang sama, baris kedua akan menjadi:

SET @a := -1;
SET @line2 = CONCAT(
    'SELECT \'Marks\',',
    (
        SELECT GROUP_CONCAT(
            CONCAT(' (SELECT Marks FROM grades LIMIT ',
                @a:[email protected]+1,
                ', 1)')
            )
        FROM grades
    ));

Menggabungkan semuanya:

Tiga variabel kami sekarang berisi:

@header:
SELECT 'id',  '1', '2' LIMIT 0, 0

@line1:
SELECT 'Name', (SELECT Name FROM grades LIMIT 0, 1),
    (SELECT name FROM grades LIMIT 1, 1)

@line2:
SELECT 'Marks', (SELECT Marks FROM grades LIMIT 0, 1),
    (SELECT marks FROM grades LIMIT 1, 1)

Kita hanya perlu membuat variabel final menggunakan CONCAT() , siapkan sebagai kueri baru dan jalankan:

SET @query = CONCAT('(',
    @header,
    ') UNION (',
    @line1,
    ') UNION (',
    @line2,
    ')'
);

PREPARE my_query FROM @query;
EXECUTE my_query;

Seluruh solusi:

(untuk pengujian dan referensi):

SET @header = CONCAT('SELECT \'id\', ',
    (SELECT GROUP_CONCAT(CONCAT(' \'', id, '\'')) FROM grades),
    ' LIMIT 0, 0');

SET @a = -1;
SET @line1 = CONCAT(
    'SELECT \'Name\',',
    (
        SELECT GROUP_CONCAT(
            CONCAT(' (SELECT Name FROM grades LIMIT ',
                @a:[email protected]+1,
                ', 1)')
            )
        FROM grades
    ));

SET @a := -1;
SET @line2 = CONCAT(
    'SELECT \'Marks\',',
    (
        SELECT GROUP_CONCAT(
            CONCAT(' (SELECT Marks FROM grades LIMIT ',
                @a:[email protected]+1,
                ', 1)')
            )
        FROM grades
    ));

SET @query = CONCAT('(',
    @header,
    ') UNION (',
    @line1,
    ') UNION (',
    @line2,
    ')'
);

PREPARE my_query FROM @query;
EXECUTE my_query;

Keluaran:

+-------+------+-------+
| id    | 1    | 2     |
+-------+------+-------+
| Name  | Ram  | Shyam |
| Marks | 45   | 87    |
+-------+------+-------+
2 rows in set (0.00 sec)

Pikiran penutup:

  • Saya masih tidak yakin mengapa Anda perlu mengubah baris menjadi kolom, dan saya yakin solusi yang saya berikan bukanlah yang terbaik (dalam hal kinerja).

  • Anda bahkan dapat menggunakan solusi saya sebagai permulaan dan mengadaptasinya ke solusi tujuan umum di mana nama kolom tabel (dan jumlah baris) tidak diketahui, menggunakan information_schema .COLUMNS sebagai sumber, tapi saya rasa itu terlalu berlebihan.

  • Saya sangat yakin bahwa jauh lebih baik untuk menempatkan tabel asli ke dalam array dan kemudian memutar array itu, sehingga mendapatkan data dalam format yang diinginkan.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Menghitung total ukuran data kolom BLOB dalam tabel

  2. Perbedaan antara MySql dan MySqli di PHP

  3. Bagaimana cara mempartisi Mysql di GANDA SERVER?

  4. Apakah ada penurunan kinerja jika ada terlalu banyak kolom dalam sebuah tabel?

  5. Di mana saya dapat menemukan daftar kode kesalahan SQLException untuk MySQL?