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

Requête de tableau croisé dynamique MySQL avec des colonnes dynamiques tronquant la valeur de la clé

Il y a plusieurs problèmes avec votre code - en diminuant la gravité :

  • vous devez sélectionner from z_tmp_admin_system_settings , pas from name
  • la colonne à regrouper s'appelle category , pas subdomain
  • puisque le principe de la requête est d'utiliser l'agrégation, vous avez besoin d'une fonction d'agrégation pour les colonnes générées, comme MAX(); les anciennes versions de MySQL tolèrent de ne pas utiliser de fonction d'agrégation sur des colonnes non agrégées, mais ce n'est pas une chose à laquelle il faut s'habituer
  • il est recommandé d'entourer le nom des colonnes de backticks, au cas où l'un des noms entrerait en conflit avec un mot réservé (ce n'est pas le cas dans votre exemple de données, mais ce n'est probablement pas exhaustif)
  • DISTINCT n'est probablement pas nécessaire, sauf si vous avez dupliqué name s par catégorie (dans ce cas, n'hésitez pas à le rajouter au code ci-dessous)
  • Remarque :IFNULL(..., NULL) est un no-op

Code :

SET SESSION group_concat_max_len = 100000;
SET @sql = '';

SELECT GROUP_CONCAT(
    CONCAT('MAX(IF(z_tmp_admin_system_settings.name = ''', name, ''', value, NULL)) AS `', name, '`')
)
INTO @sql
FROM z_tmp_admin_system_settings;
SET @sql = CONCAT(
    'SELECT category, ', 
    @sql, 
    ' FROM z_tmp_admin_system_settings GROUP BY category'
);

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

Démo sur DB Fiddle :

| category | 2fa | abc_processing_date | activate_new_approve_person | activate_new_schdule | additional_footer_for_person |
| -------- | --- | ------------------- | --------------------------- | -------------------- | ---------------------------- |
| acme     | 0   | today               | 1                           | 1                    |                              |