Преобразование строки в столбцы в MySQL

Моя таблица исходит из вывода хранимой процедуры. Это выглядит как :

col1 
A 
B
C
D

Он может иметь меньше или равно 5 строк.
Я хочу, чтобы это выглядело так

Column1  Column2 Column3  Column4  column5 
A          B      C         D       NULL

Есть ли способ добиться этого в MYSQL?

Дублировано: stackoverflow.com/questions/13581482/…

viniciusjssouza 28.05.2019 16:46

Проблема в том, что я не знаю, как я могу использовать оператор IF здесь, так как есть только один столбец, и он меняется после каждого запроса. поэтому мне не с чем сравнивать оператор IF

No_body 28.05.2019 16:48

Возможный дубликат Транспонировать запрос MySQL - нужны строки в столбцы

forpas 28.05.2019 16:51

Без столбца, который указывает порядок, вы не можете надежно преобразовать эти записи в соответствующие столбцы. Поскольку результаты/таблицы SQL определены как беспорядочный по стандартам, если только ORDER BY col1 не подходит для использования вне курса.

Raymond Nijland 28.05.2019 16:51

@RaymondNijland Честно говоря, меня не волнует порядок. Все, что я хочу, чтобы они были в один ряд. один из способов, который я делаю, похож на этот SET var1 = (SELECT listingid FROM final_table LIMIT 1); SET var2 = (SELECT listingid FROM final_table LIMIT 1,1); но я чувствую, что это будет медленнее, как если бы у меня было, скажем, 10 строк.

No_body 28.05.2019 16:55

ладно подумаю..

Raymond Nijland 28.05.2019 17:01
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
1
6
193
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

В MySQL 8+ есть довольно простой способ сделать это, используя ROW_NUMBER вместе со сводным запросом:

WITH cte AS (
    SELECT col1, ROW_NUMBER() OVER (ORDER BY col1) rn
    FROM yourTable
)

SELECT
    MAX(CASE WHEN rn = 1 THEN col1 END) AS Column1,
    MAX(CASE WHEN rn = 2 THEN col1 END) AS Column2,
    MAX(CASE WHEN rn = 3 THEN col1 END) AS Column3,
    MAX(CASE WHEN rn = 4 THEN col1 END) AS Column4,
    MAX(CASE WHEN rn = 5 THEN col1 END) AS Column5
FROM cte;

к сожалению, все же пробило на 5.1 :(

No_body 28.05.2019 16:50
"к сожалению, все же пробило на 5.1" я хотел бы, чтобы вы использовали MySQL 8 @No_body, так как вам, скорее всего, не понравится мой подход
Raymond Nijland 28.05.2019 17:28
Ответ принят как подходящий

Ниже MySQL 8.0 подход становится намного сложнее.

Простое объяснение сложной части первого запроса
Подзапрос внутри

  SELECT 
     GROUP_CONCAT(t.col1 ORDER BY col1 ASC) AS cvs
   , COUNT(*) AS t_count
  FROM 
   t

составляет список значений, разделенных запятыми. Затем генератор чисел SQL в сочетании с вложенными функциями SUBSTRING_INDEX() разбивает значения, разделенные запятыми, на записи. Который затем объединяется в одну строку с помощью GROUP_CONCAT() в пользовательскую переменную, в основном я генерирую динамический SQL, который выглядит так, '<value>' AS Column<number>[, ...] это то, что SELECT @aggregateSQLPart; показывает вам

Запрос

SET @aggregateSQLPart = NULL; 

# set max of GROUP_CONCAT higher as it defaults to 1024 bytes. 
SET SESSION group_concat_max_len = @@max_allowed_packet;

SELECT 
 DISTINCT
   GROUP_CONCAT(CONCAT("'", 
    SUBSTRING_INDEX(
       SUBSTRING_INDEX(
          t.cvs
         , ','
       , number_generator.number
      )
      , ','
      , -1 
    ) , "'" , " AS Column", number_generator.number 
 ))
INTO @aggregateSQLPart                          
FROM (
   SELECT 
     @row := @row + 1 AS number
   FROM (
      SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION   SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
      ) row1
      CROSS JOIN (
      SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION  SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
    ) row2
    CROSS JOIN (
      SELECT @row := 0 
    ) init_user_params 
  ) AS number_generator
 CROSS JOIN (
  SELECT 
     GROUP_CONCAT(t.col1 ORDER BY col1 ASC) AS cvs
   , COUNT(*) AS t_count
  FROM 
   t
 ) AS t

WHERE
 number BETWEEN 1 AND t_count;

SELECT @aggregateSQLPart;    


SET @SQL = CONCAT("
 SELECT 
 "
 , @aggregateSQLPart                                                 
);

SELECT @SQL;    

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

Результат

| Column1 | Column2 | Column3 | Column4 | Column5 |
| ------- | ------- | ------- | ------- | ------- |
| A       | B       | C       | D       | E       |

см. демо

Примечание не сомневается в производительности, он работает в среднем за 5-10 мс на «тестовом» сервере. Также обратите внимание, что я выбираю пользовательские переменные, чтобы вы могли видеть, что происходит между ними.

О... М... Г +1. На самом деле, я предпочитаю просто SELECT 'A' AS Column1, 'B' AS Column2 etc.

Tim Biegeleisen 28.05.2019 18:16

мне @TimBiegeleisen, но это был единственный способ сделать его на 100% динамичным.

Raymond Nijland 28.05.2019 18:22

Другие вопросы по теме