sql >> Database >  >> RDS >> Mysql

MySQL of PHP Transformeer rijen naar kolommen

Als u ook aparte kolommen voor uw jaren wilt hebben, moet u het jaartal toevoegen (berekend uit uw kolom date ) naar uw dynamische sql-code:

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

De kolommen krijgen de naam January_2017 , en ik heb een order by date toegevoegd , anders zouden ze meestal ongeordend zijn.

Ik heb een group by r.region , anders werkt het niet als only_full_group_by is ingeschakeld op uw server (wat de standaardwaarde is die begint met MySQL 5.7).

En ik heb een test toegevoegd voor lege tabellen (die anders tot een fout zouden leiden). Als je het niet nodig hebt en alleen delen van mijn code naar de jouwe kopieert, let dan op de ontbrekende komma na r.region in SET @sql = CONCAT('SELECT r.account, r.region ' in vergelijking met uw code, moet u deze mogelijk opnieuw toevoegen.

Aangezien de code voor elke maand een lengte heeft van ongeveer 80, moet u mogelijk group_concat_max_len verhogen om aan uw grootst mogelijke zoekopdracht te voldoen.




  1. Aparte verschillende versie van een website

  2. Time-outuitzonderingen voor SQLServer opvangen

  3. sql cross join - wat voor nut heeft iemand er voor gevonden?

  4. MySQL - Selecteer om de laatste datetime op te halen