Como já foi dito, isso não é realmente possível, o mais próximo que você pode chegar é:
January2014CalculationDate | January2014PLResult | February2014CalculationDate | February2014PLResult
---------------------------+---------------------+-----------------------------+------------------
2014-01-02 | 100 | 2014-02-03 | 300
2014-01-03 | 200 | 2014-02-04 | 400
NULL | NULL | 2014-02-27 | 500
E mesmo isso não é simples e eu ainda aconselharia lidar com formatação assim fora do sql. O primeiro passo é particionar os dados por mês e, em seguida, classificar as datas em cada mês:
SELECT CalculationDate,
PLResult,
CalculationMonth,
DenseRank = DENSE_RANK() OVER(PARTITION BY CalculationMonth ORDER BY CalculationDate)
FROM ( SELECT CalculationDate,
PLResult,
CalculationMonth = DATEADD(MONTH, DATEDIFF(MONTH, 0, CalculationDate), 0)
FROM #PLResultPerDay
) pl;
Isto dá:
CalculationDate PLResult CalculationMonth DenseRank
2014-01-02 100 2014-01-01 1
2014-01-03 200 2014-01-01 2
2014-02-03 300 2014-02-01 1
2014-02-04 400 2014-02-01 2
2014-02-27 500 2014-02-01 3
Você pode então dinamizar esses dados:
WITH Data AS
( SELECT CalculationDate,
PLResult,
CalculationMonth,
DenseRank = DENSE_RANK() OVER(PARTITION BY CalculationMonth ORDER BY CalculationDate)
FROM ( SELECT CalculationDate,
PLResult,
CalculationMonth = DATEADD(MONTH, DATEDIFF(MONTH, 0, CalculationDate), 0)
FROM #PLResultPerDay
) pl
)
SELECT Jan2014CalcDate = MIN(CASE WHEN CalculationMonth = '20140101' THEN CalculationDate END),
Jan2014Result = SUM(CASE WHEN CalculationMonth = '20140101' THEN PLResult END),
Feb2014CalcDate = MIN(CASE WHEN CalculationMonth = '20140201' THEN CalculationDate END),
Feb2014Result = SUM(CASE WHEN CalculationMonth = '20140201' THEN PLResult END)
FROM Data
GROUP BY DenseRank
ORDER BY DenseRank;
Isto dá:
Jan2014CalcDate Jan2014Result Feb2014CalcDate Feb2014Result
2014-01-02 100 2014-02-03 300
2014-01-03 200 2014-02-04 400
NULL NULL 2014-02-27 500
Então, como você tem um número dinâmico de meses, você precisa construir a instrução acima dinamicamente e usar
SP_EXECUTESQL
para executá-lo:DECLARE @SQL NVARCHAR(MAX) = '';
WITH Months AS
( SELECT M,
ColName = DATENAME(MONTH, M) + DATENAME(YEAR, M),
CharFormat = CONVERT(VARCHAR(8), M, 112)
FROM ( SELECT DISTINCT M = DATEADD(MONTH, DATEDIFF(MONTH, 0, CalculationDate), 0)
FROM #PLResultPerDay
) m
)
SELECT @SQL = 'WITH Data AS
( SELECT CalculationDate,
PLResult,
CalculationMonth,
DenseRank = DENSE_RANK() OVER(PARTITION BY CalculationMonth ORDER BY CalculationDate)
FROM ( SELECT CalculationDate,
PLResult,
CalculationMonth = DATEADD(MONTH, DATEDIFF(MONTH, 0, CalculationDate), 0)
FROM #PLResultPerDay
) pl
)
SELECT ' +
STUFF(( SELECT ', ' + ColName + 'CalculationDate = MIN(CASE WHEN CalculationMonth = ''' + CharFormat + ''' THEN CalculationDate END), ' +
ColName + 'PLResult = SUM(CASE WHEN CalculationMonth = ''' + CharFormat + ''' THEN PLResult END)'
FROM Months
ORDER BY M
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 2, '') +
'FROM Data
GROUP BY DenseRank
ORDER BY DenseRank;';
EXECUTE SP_EXECUTESQL @SQL;
Exemplo no SQL Fiddle
Observe que ainda desaconselho essa técnica e acho que o SQL deve ser deixado para armazenar/recuperar dados e a camada de apresentação para formatá-los