Mysql
 sql >> Base de données >  >> RDS >> Mysql

MySQL - Créer un enregistrement à partir d'une colonne

Ce que vous demandez est essentiellement un PIVOT mais MySQL n'a pas de fonction pivot, vous pouvez donc le répliquer en utilisant un CASE instruction avec une fonction d'agrégation.

Si vous connaissez les valeurs, vous pouvez coder en dur la solution comme ceci :

select id,
  max(case when component_id = 1 then data end) Email,
  max(case when component_id = 2 then data end) Firstname,
  max(case when component_id = 3 then data end) Lastname,
  max(case when component_id = 4 then data end) Phone
from yourtable
group by id;

Voir SQL Fiddle avec démo

Le résultat est :

| ID |            EMAIL |  FIRSTNAME |  LASTNAME |  PHONE |
-----------------------------------------------------------
|  1 | [email protected] | firstname1 | lastname1 | phone1 |
|  2 |           email2 | firstname2 | lastname2 | phone2 |

Je suppose que vous avez une table pour associer le component_id à un nom afin que votre requête puisse également être :

select t1.id,
  max(case when t2.name = 'email' then data end) Email,
  max(case when t2.name= 'FirstName' then data end) Firstname,
  max(case when t2.name= 'LastName' then data end) Lastname,
  max(case when t2.name= 'phone' then data end) Phone
from yourtable t1
inner join component t2
  on t1.component_id = t2.id 
group by t1.id;

Voir SQL Fiddle avec démo

Si vous avez un nombre inconnu de valeurs, vous pouvez utiliser une instruction préparée pour générer dynamiquement cette requête :

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when name = ''',
      name,
      ''' then data end) AS ',
      name
    )
  ) INTO @sql
FROM component;

SET @sql = CONCAT('SELECT t1.id, ', @sql, ' 
                  from yourtable t1
                  inner join component t2
                    on t1.component_id = t2.id 
                  group by t1.id');

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

Voir SQL Fiddle avec démo

Toutes les versions vous donneront le même résultat.