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

MySQL ou PHP Transformer les lignes en colonnes

Si vous souhaitez également avoir des colonnes séparées pour vos années, vous devez ajouter l'année (calculée à partir de votre colonne date ) à votre code sql dynamique :

CREATE DEFINER=`root`@`localhost` PROCEDURE `test`()
BEGIN
  SET group_concat_max_len=2048;
  SET @sql = NULL;

  SELECT GROUP_CONCAT(DISTINCT CONCAT(
      'MAX(IF(month = ''',
      month,
      ''' and year(date) = ',
      year(date),
      ', amount, NULL)) AS `',
      month,
      '_',
      year(date),
      '`'
    )
    order by date
  ) INTO @sql
  FROM tmp_results;

  if coalesce(@sql,'') != '' then
    set @sql = concat(', ', @sql);
  end if; 

  SET @sql = CONCAT(
    'SELECT r.account, 
     r.region ',  
     coalesce(@sql,''),
    ' FROM tmp_results r
     LEFT JOIN accounts AS a
     on r.account_id = a.id
     GROUP BY r.account, r.region');

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

Les colonnes seront nommées comme January_2017 , et j'ai ajouté un order by date , sinon ils seraient généralement non ordonnés.

J'ai ajouté un group by r.region , sinon cela ne fonctionnera pas si only_full_group_by est activé sur votre serveur (qui est la valeur par défaut à partir de MySQL 5.7).

Et j'ai ajouté un test pour les tables vides (ce qui entraînerait sinon une erreur). Si vous n'en avez pas besoin et ne copiez que des parties de mon code dans le vôtre, faites attention à la virgule manquante après r.region dans SET @sql = CONCAT('SELECT r.account, r.region ' par rapport à votre code, vous devrez peut-être l'ajouter à nouveau.

Étant donné que le code pour chaque mois a une longueur d'environ 80, vous devrez peut-être augmenter group_concat_max_len pour répondre à votre plus grande requête possible.