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.