Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

MySQL ou PHP Transforme linhas em colunas


Se você quiser ter colunas separadas para seus anos também, você deve adicionar o ano (calculado a partir de sua coluna date ) ao seu código sql dinâmico:
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

As colunas serão nomeadas como January_2017 , e adicionei um order by date , caso contrário, eles geralmente não seriam ordenados.

Adicionei um group by r.region , caso contrário não funcionará se only_full_group_by está habilitado em seu servidor (que é o valor padrão a partir do MySQL 5.7).

E adicionei um teste para tabelas vazias (o que resultaria em um erro). Se você não precisar dele e copiar apenas partes do meu código no seu, fique atento à vírgula ausente após r.region in SET @sql = CONCAT('SELECT r.account, r.region ' comparado ao seu código, talvez seja necessário adicioná-lo novamente.

Como o código de cada mês tem cerca de 80, talvez seja necessário aumentar group_concat_max_len para atender a sua maior consulta possível.