Nov 10 2008

Designer XI 3 New Feature: Database Delegated Measures

Categories: 2008 GBN - Dallas,Universe Design Dave Rathbun @ 7:34 am

A Brief Overview of Measure Objects

A universe has three basic types of result objects: dimensions, details, and measures. Measure objects are analytical values like dollars or quantities. Measure objects have two extra settings that dimensions and details do not have: a SQL aggregate function and a report Projection function. The SQL aggregate function is not enforced by the application, but it should always be present. (That’s a subject for another blog post. Or two.)

The SQL aggregate function is performed by the database server, and the projection function is used by the report engine. This is what makes measures “roll up” when you slice and dice or drill on a report. The problem is, certain calculations cannot be done by the database because there is no valid projection function. Designer 3.x gives me a way to address that by introducing a new projection function setting of Database delegated. This post will explain why that’s important and how it works.

How Projection Works

The projection function is designed to complement the SQL aggregation operation. For example the Revenue object from Island Resorts has the following SQL formula:

sum(INVOICE_LINE.DAYS * INVOICE_LINE.NB_GUESTS * SERVICE.PRICE)

The object also has a Sum projection function. If I run a query that returns the Resort and the Year and the Revenue the output looks like this:

Raw Data

Using a simple drag-and-drop technique I can remove the Year from the output block and the projection function causes the data to roll up to this result:

Projected Data

This is all controlled via the projection function which is a part of the object properties screen as shown here:

Projection Function

When Projection Fails

This all works very well until a special function like Average is considered. Averages cannot easily be projected because the source data could be very skewed. A sum operation can be applied recursively. What this means is that 1 + 5 generates the same result as 1 + (2 + 3). An average is not recursive. An average of 1 and 2.5 is not the same as an average of 1, 2, and 3. For the record, and average of 1 and 2.5 is 1.75, and an average of 1, 2, and 3 is 2. Even with a very small set of data the results of an average projection can be very wrong.

The basic problem here is that averages have to work with the source data. I cannot apply an average to an average and expect to get the correct result. It is for this reason that report developers have had to create average and percentage calculations on their reports rather than reusing an object from a universe. In order to deliver the correct result I have to work with the source data.

Averages Do Not Average Well

As I said in the prior paragraph, the only way to generate the correct result for an average is to recalculate it from the source data. In order to demonstrate this I have created an Average Revenue object in my universe. For this screen shot I have used the average object in two different queries. The first shows Average Revenue by Resort and Year, and the second shows Average Revenue by Resort only.

Average Data

The object is created with the following SQL:

avg(INVOICE_LINE.DAYS * INVOICE_LINE.NB_GUESTS * SERVICE.PRICE)

… and the projection function is set to Average. As I did before I can apply a simple drag-and-drop operation to remove the Year object from the first block, allowing the report engine to project the Average Revenue using the selected projection function of Average. Are the results correct?

Projected Average Data

The results are wrong because the projection in the first block is taking three years of data, summing them up, and then dividing the total by three to get the new average value. The true result based on a database calculation is shown in the right block. The second block was not affected by the Year values since the query did not include that object in the result set.

Delegated Measures

This is where the delegation process comes in. As a universe designer I can now create an object that will project correctly (yay) at the expense of having to run a database query (boo). Instead of projecting my average calculation using the Average function, I will use the Database Delegated option instead. Here’s how that looks:

Delegated Projection

When I run the same query with my new measure definition here is what the initial output looks like:

Average Data

The difference becomes apparent when I drag-and-drop the Year object away from my block:

Average Data

The note #TOREFRESH is telling me that before I can see the numbers for that column I have to refresh my document. I think that it’s nice that it doesn’t refresh right away, as it gives me the opportunity to make more adjustments. Perhaps on a more complex report I want to remove (or add) more than one object from the block. In any case, when I click the refresh button the results are displayed.

Average Data

Note that the two blocks are 100% the same now. The option to delegate the average calculation to the database has given me the power to create an entirely new type of object that I could not have done before.

Conclusion

This is another nice new feature for Designer. It will provide me with better control over how my measure objects are handled. In this case, the solution is not without a cost… I may have to refresh the report in order to force the data to be updated. If the query takes a long time to run, there is a cost involved. It may ultimately still be easier to do this type of calculation on the report.

Here is another challenge that is not solved by this technique: I can’t do calculations that cross contexts in the universe. Suppose that I have one context for current year measures, and a second context for prior year measures. If I want to compare current to prior year values, that has to be done on the report. Delegating that calculation to the database is not possible because the values come from two different contexts.

But it’s nice to have options.

This feature was one of several mentioned in my Designer Essentials presentation delivered at the 2008 GBN conference. This particular feature was on page 10.

54 Responses to “Designer XI 3 New Feature: Database Delegated Measures”

  1. Comment by Dave Rathbun

    A database delegated value is only valid in the context of the query. If you apply filters (and I suspect even drill filters fit this category) then the query really needs to be refreshed in order to get the correct result.

  2. Comment by Dave Rathbun

    I am not aware of any database-specific issues with the delegated feature. The SQL itself does not change when using this feature. What changes would be when the SQL gets executed. With this feature on, each time a user wants to project measures they will have to refresh the data for the report.

  3. Comment by Nash

    Hi Dave,
    I have a ratio calculation (E.g. Share of Market% where numerator is sum of volume sales for a product divided by total sum of volume sales across the entire product category). I have to deliver this as a single measure in the unv, which must support drill down across geography, product & time dimensions.
    Since this is a non-additive fact, do you have any suggestions regarding its implementation in the universe? I tried making this database delegated but it doesn’t seem to add a lot of value since arriving at the denominator itself seems to be a problem as it changes based on the dimensions selected by the user.
    I suggested that it needs to be done on the report, but the users are insistent!

    Thanks,
    Nachiketa

  4. Comment by Dave Rathbun

    Hi, Nachiketa, unfortunately I think you’ll find that you need to be equally insistent. When there is a ratio of any kind, the database delegated option is really the only solution, as we need to ensure that the proper values are used in the calculation. There is some hope in the future that we might get “universe hosted variables” which would be another option, but that doesn’t help you today…