Tuesday, September 20, 2022

How to Create Dynamic Pivot Tables in MySQL

Загрузка данных в таблицу:


boris@UbuntuLTS:~$ mysql -u root -p

Enter password: 

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 15

Server version: 8.0.30-0ubuntu0.22.04.1 (Ubuntu)

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create database dynamic;

Query OK, 1 row affected (0,14 sec)

mysql> use dynamic;

Database changed

mysql> show databases ;

+--------------------+

| Database           |

+--------------------+

| dynamic            |

| information_schema |

| mysql              |

| performance_schema |

| sys                |

+--------------------+

5 rows in set (0,00 sec)

mysql> CREATE TABLE Meeting

    -> (

    ->     ID INT,

    ->     Meeting_id INT,

    ->     field_key VARCHAR(100),

    ->     field_value VARCHAR(100)

    -> );

Query OK, 0 rows affected (0,80 sec)


mysql> INSERT INTO Meeting(ID,Meeting_id,field_key,field_value)

    -> VALUES (1, 1,'first_name' , 'Alec');

Query OK, 1 row affected (0,11 sec)

mysql> INSERT INTO Meeting(ID,Meeting_id,field_key,field_value)

    -> VALUES (2, 1,'last_name' , 'Jones');

Query OK, 1 row affected (0,13 sec)

mysql> INSERT INTO Meeting(ID,Meeting_id,field_key,field_value)

    -> VALUES (3, 1,'occupation' , 'engineer');

Query OK, 1 row affected (0,14 sec)

mysql> INSERT INTO Meeting(ID,Meeting_id,field_key,field_value)

    -> VALUES (4,2,'first_name' , 'John');

Query OK, 1 row affected (0,13 sec)

mysql> INSERT INTO Meeting(ID,Meeting_id,field_key,field_value)

    -> VALUES (5,2,'last_name' , 'Doe');

Query OK, 1 row affected (0,30 sec)

mysql> INSERT INTO Meeting(ID,Meeting_id,field_key,field_value)

    -> VALUES (6,2,'occupation' , 'engineer');

Query OK, 1 row affected (0,08 sec)

Допустим, вы хотите создать динамическую сводную таблицу, чтобы новый столбец создавался для каждого уникального значения в столбце field_key, то есть (имя, фамилия, род занятий).  Если вы уже знаете, какие столбцы создавать в сводной таблице, вы можете использовать 

оператор CASE для создания сводной таблицы. Однако для создания динамических сводных таблиц в MySQL мы используем функцию GROUP_CONCAT для динамического переноса строк в столбцы, как показано ниже.


mysql> select * from Meeting;

+------+------------+------------+-------------+

| ID   | Meeting_id | field_key  | field_value |

+------+------------+------------+-------------+

|    1 |          1 | first_name | Alec        |

|    2 |          1 | last_name  | Jones       |

|    3 |          1 | occupation | engineer    |

|    4 |          2 | first_name | John        |

|    5 |          2 | last_name  | Doe         |

|    6 |          2 | occupation | engineer    |

+------+------------+------------+-------------+

6 rows in set (0,00 sec)


GROUP_CONCAT позволяет объединять значения из нескольких строк в одну строку. В приведенном ниже запросе мы используем GROUP_CONCAT для динамического создания операторов CASE на основе уникальных значений в столбце field_key и сохранения этой строки в переменной @sql.  Затем он используется для создания нашего запроса на выборку.

mysql> SET @sql = NULL;

Query OK, 0 rows affected (0,00 sec)


mysql> SELECT

    ->   GROUP_CONCAT(DISTINCT

    ->     CONCAT(

    ->       'max(case when field_key = ''',

    ->       field_key,

    ->       ''' then field_value end) ',

    ->       field_key

    ->     )

    ->   ) INTO @sql 

    -> FROM

    ->   Meeting;

Query OK, 1 row affected (0,00 sec)


mysql> SET @sql = CONCAT('SELECT Meeting_id, ', @sql, ' 

    '>                   FROM Meeting 

    '>                    GROUP BY Meeting_id');

Query OK, 0 rows affected (0,00 sec)


mysql> PREPARE stmt FROM @sql;

Query OK, 0 rows affected (0,00 sec)

Statement prepared



mysql> EXECUTE stmt;

+------------+------------+-----------+------------+

| Meeting_id | first_name | last_name | occupation |

+------------+------------+-----------+------------+

|          1 | Alec       | Jones     | engineer   |

|          2 | John       | Doe       | engineer   |

+------------+------------+-----------+------------+

2 rows in set (0,00 sec)


mysql> DEALLOCATE PREPARE stmt;

Query OK, 0 rows affected (0,00 sec)













No comments:

Post a Comment