MySQL peut-il convertir des colonnes en lignes, en ajoutant dynamiquement autant de colonnes que nécessaire pour les lignes. Je pense que ma question pourrait être liée aux tableaux croisés dynamiques, mais je ne suis pas sûr et je ne sais pas comment cadrer cette question autrement qu'en donnant l'exemple suivant.
Étant donné deux tableaux A et B, qui ressemblent à
Tableau A
+--+-----+----+
|id|order|data|
+--+-----+----+
|1 |1 |P |
+--+-----+----+
|2 |2 |Q |
+--+-----+----+
|2 |1 |R |
+--+-----+----+
|1 |2 |S |
+--+-----+----+
J'aime écrire une requête qui ressemble à ceci:
Tableau des résultats
+--+-----+-----+
|id|data1|data2|
+--+-----+-----+
|1 |P |S |
+--+-----+-----+
|2 |R |Q |
+--+-----+-----+
Fondamentalement, je veux transformer chaque ligne du tableau B en une colonne du tableau des résultats. S'il y avait une nouvelle entrée a été ajoutée à la table B pour id = 1, alors je veux que la table de résultat s'étende automatiquement d'une colonne pour accueillir ce point de données supplémentaire.
Vous pouvez utiliser GROUP BY
et MAX
pour simuler le pivot. MySQL prend également en charge l'instruction IF
.
SELECT ID,
MAX(IF(`order` = 1, data, NULL)) data1,
MAX(IF(`order` = 2, data, NULL)) data2
FROM TableA
GROUP BY ID
Si vous avez plusieurs valeurs de order
, le SQL dynamique peut être plus approprié pour que vous n'ayez pas à modifier la requête:
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(IF(`order` = ', `order`, ',data,NULL)) AS data', `order`)
) INTO @sql
FROM TableName;
SET @sql = CONCAT('SELECT ID, ', @sql, '
FROM TableName
GROUP BY ID');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SORTIE DES DEUX DEMANDES:
╔════╦═══════╦═══════╗
║ ID ║ DATA1 ║ DATA2 ║
╠════╬═══════╬═══════╣
║ 1 ║ P ║ S ║
║ 2 ║ R ║ Q ║
╚════╩═══════╩═══════╝
Vous devez utiliser MAX
et GROUP BY
pour simuler un PIVOT:
SELECT Id,
MAX(CASE WHEN Order = 1 THEN data END) data1,
MAX(CASE WHEN Order = 2 THEN data END) data2
FROM TableA
GROUP BY Id
Et voici le SQL Fiddle .