Как получить данные из двух таблиц со строками в виде столбцов? (динамический пивот в MySQL)

0

У меня есть две таблицы (таблица 1 и таблица 2) в моем MySQL db, как показано ниже. Я хочу получить данные из двух таблиц, как и в таблице 3, если мои таблицы 1 увеличиваются, то столбцы таблицы 3 увеличиваются. Возможно ли получить данные по одному запросу mysql?

CREATE TABLE 'table_1' (
  'id' smallint(4) NOT NULL,
  'name' varchar(31) NOT NULL,
  'price' decimal(6,2) NOT NULL DEFAULT '0.00',
  'status' tinyint(1) NOT NULL DEFAULT '1'
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO 'table_1' ('id', 'name', 'price', 'status') VALUES
(1, 'name1', '1.00', 1),
(2, 'name2', '2.00', 1),
(3, 'name3', '3.00', 1),
(4, 'name4', '5.00', 1),
(5, 'name5', '10.00', 1),
(6, 'name6', '15.00', 1),
(7, 'name7', '20.00', 1),
(8, 'name8', '50.00', 1);

CREATE TABLE 'table_2' (
  'id' mediumint(6) NOT NULL,
  'table1_id' smallint(4) NOT NULL,
  'qry' smallint(4) NOT NULL DEFAULT '1',
  'total' decimal(6,2) NOT NULL DEFAULT '0.00',
  'date' date NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO 'table_2' ('id', 'table1_id', 'qry', 'total', 'date') VALUES
(1, 1, 10, '10.00', '2017-12-02'),
(2, 2, 20, '40.00', '2017-12-02'),
(3, 3, 10, '30.00', '2017-12-02'),
(4, 5, 5, '50.00', '2017-12-02'),
(5, 4, 20, '100.00', '2017-12-03'),
(6, 6, 10, '150.00', '2017-12-03'),
(7, 7, 5, '100.00', '2017-12-03'),
(8, 8, 2, '100.00', '2017-12-03');

Изображение 174551

Теги:

1 ответ

1
Лучший ответ

Ваше требование называется "динамическим сводным запросом", поскольку преобразование данных в заголовки столбцов невозможно в стандартном SQL. Вы должны написать запрос, который будет генерировать новый запрос для вас.

Сгенерированный код запроса будет выглядеть так:

SELECT t2.'date'
 , max(CASE WHEN name = 'name1' THEN t2.total END) AS name1
 , max(CASE WHEN name = 'name2' THEN t2.total END) AS name2
 , max(CASE WHEN name = 'name3' THEN t2.total END) AS name3
 , max(CASE WHEN name = 'name4' THEN t2.total END) AS name4
 , max(CASE WHEN name = 'name5' THEN t2.total END) AS name5
 , max(CASE WHEN name = 'name6' THEN t2.total END) AS name6
 , max(CASE WHEN name = 'name7' THEN t2.total END) AS name7
 , max(CASE WHEN name = 'name8' THEN t2.total END) AS name8
FROM table_1 t1
INNER JOIN table_2 t2 ON t1.id = t2.id
GROUP BY t2.'date'

Для создания этого запроса используйте следующее (это Dynamic SQL Query)

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when t1.name = ''',
      Name,
      ''' then t2.total end) AS ',
      replace(Name, ' ', '')
    )
  ) INTO @sql
from Table_1;

SET @sql = CONCAT(
'SELECT t2.'date', '
, @sql
, ' from table_1 t1
inner join table_2 t2 on t1.id = t2.id
group by t2.'date'');

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

см. эту демонстрацию

+---------------------+-------+-------+-------+-------+--------+--------+--------+--------+
|        date         | name1 | name2 | name3 | name4 | name5  | name6  | name7  | name8  |
+---------------------+-------+-------+-------+-------+--------+--------+--------+--------+
| 02.12.2017 00:00:00 | 10,00 | 40,00 | 30,00 | 50,00 | NULL   | NULL   | NULL   | NULL   |
| 03.12.2017 00:00:00 | NULL  | NULL  | NULL  | NULL  | 100,00 | 150,00 | 100,00 | 100,00 |
+---------------------+-------+-------+-------+-------+--------+--------+--------+--------+
  • 0
    "max (CASE WHEN name = 'name1' THEN t2.total END) AS name1" эта часть нужна динамически, потому что в моей строке таблицы 1 увеличивается, а столбец увеличивается
  • 0
    Извините, что означает этот комментарий?
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню