sql >> Databasteknik >  >> RDS >> Mysql

MySQL eller PHP Förvandla rader till kolumner

Om du vill ha separata kolumner för dina år också måste du lägga till året (beräknat från din kolumn date ) till din dynamiska SQL-kod:

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

Kolumnerna kommer att heta som January_2017 , och jag lade till en order by date , annars skulle de vanligtvis vara oordnade.

Jag lade till en group by r.region , annars fungerar det inte om only_full_group_by är aktiverat på din server (vilket är standardvärdet som börjar med MySQL 5.7).

Och jag lade till ett test för tomma tabeller (som annars skulle resultera i ett fel). Om du inte behöver det och bara kopierar delar av min kod till din, var medveten om det saknade kommatecken efter r.region i SET @sql = CONCAT('SELECT r.account, r.region ' jämfört med din kod kanske du måste lägga till den igen.

Eftersom koden för varje månad har en längd på cirka 80, kan du behöva öka group_concat_max_len för att passa din största möjliga fråga.




  1. Utöka användningen av DBCC CLONEDATABASE

  2. Composite PRIMARY KEY upprätthåller NOT NULL-begränsningar på inblandade kolumner

  3. Hur make_timestamptz() fungerar i PostgreSQL

  4. Hur ADDDATE() fungerar i MariaDB