abela dinâmica @MySQL com cabeçalhos dinâmicos com base em dados de coluna única

Estou tentando escrever uma consulta para criar uma 'tabela' de dados da seguinte maneira:

SELECT cs.`category_id`, cs.`ProcessDate`, cs.`PercentChange`
  FROM `Category_Statistics` cs
 WHERE cs.`ProcessDate` >= '2011-05-10'
   AND cs.`ProcessDate` <= '2011-05-14'

O que retornaria algo como:

CategoryId  |  ProcessDate  | PercentChange
-------------------------------------------
category_4  |  2011-05-10   |      10
category_4  |  2011-05-11   |      18
category_4  |  2011-05012   |      12
...
category_7  |  2011-05-10   |      21
category_7  |  2011-05-11   |      7
...
category_12 |  2011-05-10   |      7
category_12 |  2011-05-11   |      15

gora, eu quero que os resultados sejam algo assim (de uma consulta MySQL, não manipulada pelo aplicativo

CategoryId    | 2011-05-10 | 2011-05-11 | 2011-05-12 | 2011-05-13 | 2011-05-14 |
--------------------------------------------------------------------------------
category_4    |     10     |     18     |     12     |      9     |      14    |
category_7    |     21     |      7     |     16     |      14    |      13    |
categeory_12  |      7     |     15     |     11     |      19    |       8    |
--------------------------------------------------------------------------------

Existem duas advertências para isso:

O período pode aumentar ou diminuir (dependendo da consulta)

PercentChange pode ser nulo em alguns casos (digamos que category_7 / 2011-05-12 pode não ter um valor definido)

or fim, não tenho muita certeza de como criar a parte selecionada da consulta para refletir um número dinâmico de colunas (eu sei que isso tem algo a ver com o CONCAT

Editar -> Código de trabalho parcial ->

SELECT `CategoryId`,
   MAX(IF(c.`ProcessedOn` = '2011-04-20', c.`PercentChange`, NULL)) AS '2011-04-20',
   MAX(IF(c.`ProcessedOn` = '2011-04-21', c.`PercentChange`, NULL)) AS '2011-04-21',
   MAX(IF(c.`ProcessedOn` = '2011-04-22', c.`PercentChange`, NULL)) AS '2011-04-22',
   MAX(IF(c.`ProcessedOn` = '2011-04-23', c.`PercentChange`, NULL)) AS '2011-04-23',
   MAX(IF(c.`ProcessedOn` = '2011-04-24', c.`PercentChange`, NULL)) AS '2011-04-24'
  FROM `Category_Gravity` c
 WHERE c.`ProcessedOn` >= '2011-04-20'
   AND c.`ProcessedOn` <= '2011-04-24'
 GROUP BY `CategoryId`

O que eu preciso fazer agora é ativar o

MAX(IF(c.`ProcessedOn` = '2011-04-20', c.`PercentChange`, NULL)) AS '2011-04-20',

m algo mais dinâmico (pois os períodos mudarã

questionAnswers(1)

yourAnswerToTheQuestion