In the previous post in this series, Agile: Creating an SSRS Burndown Chart Part 1, I explained what data you would need to prepare to create an SSRS Burndown Chart (Sprint_Dates, Stories, Story_History). In this part of the series I will explain how to get a basic burndown report in SSRS.
First, fire up Report Builder 3.0 and create a new report (if the wizard pops up, just pick “Blank Report”). You need to add a Data Source to your report. In my example, I am just using a database on my localhost called Agile, so I connect to that and create a report Data Source.
We then need to add 3 Datasets to the report. (Burndown, Sprints, and CurrentSprint), and one parameter (Sprint) and we can then format our report.
Sprints (this will be a dropdown of Sprints for a user to choose from)
CurrentSprint (this will get the current sprint based on what day we view the report, default param for the Sprint parameter we will create)
For the Burndown, do the same thing, but since the query is so large, no screenshot, just the query:
;WITH DayHistory AS ( SELECT bd.[DATE] ,bd.PointsScheduled ,bd.PointsLeft ,bd.PointsScheduled - ((ROW_NUMBER() OVER (ORDER BY bd.[DATE]) - 1) * (CAST(bd.PointsScheduled AS DECIMAL(15,6))/10.0)) AS 'Goal' ,ROW_NUMBER() OVER (ORDER BY bd.[DATE]) AS [DayNumber] FROM ( SELECT tot.Sprint,tot.LogDate AS [DATE], CASE WHEN SUM(tot.PointsScheduled) = 0 THEN (SELECT SUM(Points) FROM dbo.Stories st WHERE Sprint = 'Sprint01') ELSE SUM(tot.PointsScheduled) END AS 'PointsScheduled', SUM(tot.PointsLeft) AS 'PointsLeft' FROM ( -- Get History for the Current Sprint SELECT Sprint,LogDate,SUM(Points) AS 'PointsScheduled', SUM(PointsLeft) AS 'PointsLeft' FROM dbo.Story_History st WHERE Sprint = @Sprint GROUP BY Sprint,LogDate UNION -- Get the Current Day SELECT Sprint AS 'Sprint',CAST(GETDATE() AS DATE) AS 'LogDate', SUM(Points) AS 'PointsScheduled', SUM(PointsLeft) AS 'PointsLeft' FROM dbo.Stories WHERE Sprint = @Sprint GROUP BY Sprint UNION -- Get zero's for all days in sprint to round out our dataset SELECT 'Sprint01' AS 'Sprint',WorkDate,0,0 FROM dbo.Sprint_Dates WHERE Sprint = @Sprint ) tot GROUP BY tot.Sprint,tot.LogDate ) bd ) SELECT a.[DATE] ,ISNULL(b.PointsScheduled, a.PointsScheduled) AS [PointsScheduled] ,ISNULL(b.PointsScheduled, a.[PointsLeft]) AS [PointsLeft] ,ISNULL(b.PointsScheduled, a.[Goal]) AS [Goal] FROM DayHistory a LEFT OUTER JOIN DayHistory b ON a.DayNumber = b.DayNumber - 1 AND b.DayNumber = 2 ORDER BY DATE
This query is where all the magic happens. First, you need to get your story point values for the days, from your history, and also from the current day, you also need to get all days for that sprint with zero’s so that your graph will have all days and not just days with burndown. The CTE around the main query calculates the burndown by day so you end up with 4 columns, Date, PointsScheduled, PointsLeft, Goal
Now that you have your Datasets, we need to create a parameter, and then the graph!
Create a new parameter called “Sprint”, and set up the available values. Remember the Dataset we created to get all the sprints? Here is where you use it, like this:
Next, we want to setup the default values. Remember the query to get the “Current Sprint” – that is used to set our default.
Once you have that all setup, it is time to build the graph!
We are really close to having a working report here, and check back for part 3 of the series to get the graph working correctly, and part 4 for beautification!