MartinM
MartinM

Reputation: 1806

Populating with '0' when Data in SSRS Does not exist

I'm trying to create a report in SSRS where I have a matrix, which has gender as the column headings and specifically defined agegroups as the rows. The report is sorted by date (ie, the records being displayed are filtered by the modifedAt value). My problem is that i wish for all of the age group categories to be displayed, even if the dataset does not return any data for that row.

So, for example, if i set the date to be a date where there are no db rows where there are Age5-16 children in - I still want to display the category name, but just have the cells related to that row to display '0'. Instead, the report just drops the whole row because, obviously the query returns no data.

Is the solution to have a separate dataset that brings back the entire list of categories and then somehow fit them together? I'm stuck here so any help is appreciated!

Upvotes: 1

Views: 14385

Answers (2)

Floydius
Floydius

Reputation: 33

I know this is old, but I wanted to elaborate on Ian's section 1 above using joins at the dataset level. (His answer was super helpful to me for a report I'm working on.)

per op:

Is the solution to have a separate dataset that brings back the entire list of categories and then somehow fit them together?

That is how I've handled it successfully, but you can do so without actually creating a separate dataset by using common table expressions (or temp tables, of course).

For these example tables:

       AGE_Table
    ID   Group     Group_Desc    Toys
    1    A         00-10        Teddy Bear
    2    B         11-20        Video Game
    3    C         21-30        Sports Car
    4    D         31-40        Mansion
    5    E         41-50        Jewelry

                 People_Table  (filtered for whatever date)
    ID    Name          Age    Gender   Age_Group
    1     Ariel         07     F        A
    2     Brandon       23     M        C
    3     Chelsea       27     F        C
    4     Derek         06     M        A

You want to see 2 results for the 00-10 row, 2 for the 21-30 row, and then still see rows for the other age groups even if there aren't any results.

We want to create a dataset with all the different age groupings and then join on it. Behold a solution using common table expressions:

    with CTE_Age AS
    (SELECT Distinct Age_Group from AGE_Table)

    SELECT ID, Name, Age, Gender, CTE_Age.Age_Group FROM People_Table
    RIGHT JOIN CTE_Age ON
    People_Table.Age_Group = CTE_Age.Age_Group

This will return:

    ID     Name        Age     Gender     Age_Group
    1      Ariel       7       F          A
    4      Derek       6       M          A
    NULL   NULL        NULL    NULL       B
    2      Brandon     23      M          C
    3      Chelsea     27      F          C
    NULL   NULL        NULL    NULL       D
    NULL   NULL        NULL    NULL       E

Once you have that in your dataset, you can change NULL values to 0 on the report builder side -- I think in 2008R2 the default is just blank.

Upvotes: 2

Ian Preston
Ian Preston

Reputation: 39586

I can think of a few ways to do this:

DataSet level

Instead of just returning the relevant data in the underlying data in the DataSet, include all the categories you want to display in all cases.

e.g. For a database query it might be the difference between an inner and left join, i.e. going from something like:

select *
from AgeGroup
  inner join MyData on ...

to:

select *
from AgeGroup
  left join MyData on ...

So the report always has all the age groups to display. Where there are NULL values, just display 0.

I think this is the best option if you have control over the DataSet - you won't have to update your report at all, with luck the actual DataSet changes should be minimal, there is still only one DataSet call, and it's by far the simplest to maintain.

Hard code groups into the report

Here you include a table header row for each group you want to display, so these are always displayed in all cases.

Here you have some sort of conditional expression to display the values, e.g. For each group row it will be tailored to that group:

=Sum(IIf(Fields!AgeGroup.Value = "5-16", Fields!Amount.Value, Nothing)

This is not too flexible and will need updates as you change groups, and doesn't have as many options for layout. There is still only one DataSet call, so that is a plus.

Subreports

You can have a parent DataSet that displays one row for each age group, then embed a subreport in each row that displays the data you want for that row.

This allows you flexibility in layout but it will add complexity to the report(s) and will mean that you make a lot of DataSet calls that could be avoided with other options.

Upvotes: 3

Related Questions