/*************************************************************************************************
** File:
"jesse_mclain_tsqlchallenge_12.sql"
** Desc: solution for TSQL Challenge #12
** http://beyondrelational.com/blogs/tc/archive/2009/08/09/tsql-challenge-12-build-sequential-ranges-of-dates-with-propagation-to-missing-values.aspx
**
**
** Auth:
Jesse McLain
** Email: mailto:jesse@jessemclain.com
** Web:
http://www.jessemclain.com
** Blog:
http://www.jessesql.blogspot.com
**
** Date:
09/02/2009
**
**************************************************************************************************/
DECLARE @Scores TABLE(YearMonth INT, Score INT)
INSERT @Scores VALUES(200903, 100)
INSERT @Scores VALUES(200803, 95)
INSERT @Scores VALUES(200802, 99)
INSERT @Scores VALUES(200801 ,100)
INSERT @Scores VALUES(200711, 100)
;WITH BaseScores
AS (
SELECT
YearMonth,
Score,
ParsedDate = CONVERT(datetime,
SUBSTRING(CONVERT(char(6), YearMonth), 5, 2) + '/1/' + LEFT(YearMonth, 4))
FROM @Scores
/* this
recursive CTE picks the earliest score date and builds a table of each month
between then
and the current date */
), AllMonths AS (
SELECT
ParsedDate,
Score
FROM BaseScores
WHERE ParsedDate = (SELECT MIN(ParsedDate) FROM BaseScores)
UNION ALL SELECT
ParsedDate = DATEADD(m, 1, AllMonths.ParsedDate),
Score = ISNULL((SELECT Score FROM
BaseScores
WHERE BaseScores.ParsedDate = DATEADD(m, 1, AllMonths.ParsedDate)),
AllMonths.Score)
FROM AllMonths
WHERE DATEADD(m, 1, AllMonths.ParsedDate) <= GETDATE()
)
SELECT
YearMonth = CONVERT(int, LEFT(REPLACE(CONVERT(VARCHAR, ParsedDate, 102), '.', ''), 6)),
Score
FROM AllMonths
ORDER BY 1 DESC