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.