Skip to main content

Use case

Sometimes, there’s a need to calculate an aggregation over facts in a joined cube that is filtered by a dimension from another cube. For example, you might want to calculate the total sales for a retailer. Each retailer has multiple stores, and each store does its own sales. If you set sales goals at the retailer level and are only interested in the sales that happened after a certain date, you would need to calculate the total sales in a way that only includes sales that happened after that date.

Data modeling

We can model this scenario by creating a cube for each entity: retailer, store, and sales. The retailer cube has a one-to-many relationship with the store cube, and the store cube has a one-to-many relationship with the sales cube:
The total sales for a store and total sales for a retailer are calculated via subquery dimensions. If you look at the join path (retailer.store.sales), you would see the upstream flow of data: the aggregation over sales is passed from the sales cube to the store cube and then to the retailer cube. At the same time, the goal_start date is passed from the retailer cube to the store cube and then to the sales cube, creating the downstream flow of data. This way, the total_sales_for_goal measure in the sales cube can be filtered by the goal_start date. This pattern of passing measures (aggregates) upstream by the join path and passing dimensions downstream is an effective way to solve many data modeling tasks, including calculating filtered aggregates.

Result

Querying the retailer cube will return the total sales for each retailer and the total sales for each retailer after the goal_start date. The sales_goal_achieved measure will show the ratio of the sales goal that has been achieved: