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

Renommer les colonnes d'une table en colonnes selon un mapping défini dans une autre table - avec MYSQL

Je crois comprendre que vous voulez sélectionner une colonne par son nom, et les noms sont des chaînes dans votre TABLE_MASTER.

Vous ne pouvez pas le faire dans une seule requête SQL, car SQL ne peut pas sélectionner une colonne à l'aide d'une expression de chaîne. Il y a une différence entre une chaîne et un identifiant. Par exemple, cela sélectionne les données d'une colonne par identifiant :

SELECT header01 ...

Mais ce qui suit est une expression de chaîne (simple, qui est juste une valeur constante). Il renvoie uniquement une chaîne fixe 'header01', PAS les données d'une colonne de ce nom :

SELECT 'header01' ...

De même, l'utilisation de toute autre expression dans une liste de sélection ne sélectionne que la valeur de cette expression, PAS les données stockées dans une colonne nommée par la valeur de chaîne de l'expression.

Par conséquent, si vous souhaitez qu'une requête renvoie une colonne dynamique nommée par une autre variable ou expression, vous ne pouvez pas le faire dans la même requête où vous lisez cette expression. Vous devez formater une nouvelle requête SQL à partir des valeurs que vous lisez. C'est ce qu'on appelle une instruction SQL dynamique (déjà mentionné par spencer7593, qui a posté une réponse pendant que j'écrivais ma propre réponse).

Vous pouvez utiliser votre TABLE_MASTER pour formater une instruction SQL dynamique afin de récupérer des colonnes et de redéfinir leur alias :

SELECT CONCAT(
  'SELECT ', 
   GROUP_CONCAT(CONCAT(ORIGIN, ' AS ', TARGET)), ', ', 
   QUOTE(MAX(NAME)), ' AS NAME ',
  'FROM TABLE_EXAMPLE'
) INTO @sql
FROM TABLE_MASTER;

Le résultat est une chaîne qui forme une autre instruction SELECT, celle-ci renomme les colonnes comme vous le souhaitez :

SELECT header01 AS header_master01,header02 AS header_master02, 'Paul' AS NAME FROM TABLE_EXAMPLE  

Ensuite, vous pouvez utiliser la chaîne stockée dans @sql en tant que requête SQL dynamique.

Voici la procédure qui fait cela :

DELIMITER ;;

CREATE PROCEDURE MyProc()
BEGIN
    SELECT CONCAT(
      'SELECT ', 
       GROUP_CONCAT(CONCAT(ORIGIN, ' AS ', TARGET)), ', ', 
       QUOTE(MAX(NAME)), ' AS NAME ',
      'FROM TABLE_EXAMPLE'
    ) INTO @sql
    FROM TABLE_MASTER;
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
END

DELIMITER ;

Appelez la procédure, et obtenez le résultat :

CALL MyProc();

+-----------------+-----------------+------+
| header_master01 | header_master02 | NAME |
+-----------------+-----------------+------+
| data01          | data02          | Paul |
| data11          | data12          | Paul |
+-----------------+-----------------+------+

Je dois dire que c'est beaucoup de mal à traverser. Je préférerais récupérer les données telles qu'elles sont dans la base de données et les reformater dans mon code d'application. Je n'aurais alors pas besoin d'utiliser de SQL dynamique pour formater les colonnes.