sql >> Base de Datos >  >> RDS >> Mysql

MySQL o PHP Transformar filas en columnas

Si también desea tener columnas separadas para sus años, debe agregar el año (calculado a partir de su columna date ) a su 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

Las columnas se llamarán como January_2017 , y agregué un order by date , de lo contrario, normalmente estarían desordenados.

Agregué un group by r.region , de lo contrario no funcionará si only_full_group_by está habilitado en su servidor (que es el valor predeterminado a partir de MySQL 5.7).

Y agregué una prueba para tablas vacías (que de lo contrario daría como resultado un error). Si no lo necesita y copia solo partes de mi código en el suyo, tenga en cuenta la coma que falta después de r.region en SET @sql = CONCAT('SELECT r.account, r.region ' en comparación con su código, es posible que deba agregarlo nuevamente.

Dado que el código de cada mes tiene una longitud de aproximadamente 80, es posible que deba aumentar group_concat_max_len para adaptarse a su consulta más grande posible.