Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Find everything you need to get certified on Fabric—skills challenges, live sessions, exam prep, role guidance, and more. Get started

Reply
daxreport
Frequent Visitor

Calculation group Nesting of measures

Hello All, 

 

I understand we can't do nesting of calculation items as it would result in sideways recursion and this is not recommended. However, I am confused about nesting of measures in a calculation item and how that would affect the results. If we have a calculation item that references a measure which in turn references other measures, is it supposed to work fine?

 

As an example, consider I am calculating a price variances using a dax code simliar to this. This is for MTD Price Variance. If I execute a calculation item for YTD, somehow the result generated is the correct one.

 

As you can see below, price variance is based on other variables (like CY Price, PY Price and PY Sales) and I am very surprised that calculation grouping is working despite these nested measures. Is this just by luck or is the calculation group meant to acheive this kind of behavior? 

I thought in this article by SQL BI it said it is not possible to propogate measure references used in nested calculation and perhaps I am not understanding the context in which that comment was made. Thanks 

 

https://www.sqlbi.com/articles/using-calculation-groups-to-selectively-replace-measures-in-dax-expre...

 

VAR CY Price =
[CY Sales]/[QTY]

VAR PY Sales =
CALCULATE ([CY Sales], SAMEPERIODLASTYEAR ('Date'[Date])

VAR PY Price =
[PY Sales]/[PY Qty]

VAR Price Variance =
([CY Price]-[PY Price])*[QTY]

1 ACCEPTED SOLUTION
OwenAuger
Super User
Super User

Hello @daxreport 

I think the part of the SQLBI article you're referring to is:

 

Because the [measure reference] replacement takes place only at the report level where the calculation groups are usually applied, it is not possible to propagate the replacement to measure references used in nested calculations. This behavior limits your ability to apply calculation groups only to a specific subexpression of a complex DAX calculation. 

 

My short explanation of this would be:

  • When Calculation Groups are used in the "usual" way, that is by adding a measure to a visual in a report and applying a filter on a particular Calculation Item, the measure used in the report is in its entirety replaced by the Calculation Item.
  • However, if you want to restrict the Calculation Item to apply just to a sub-measure or sub-expression within the definition of the measure used in the report, this cannot be done when Calculation Groups are used in the usual way.
  • In order to solve this issue, the author of the article shows how the model can be modified and the Calculation Item thena applied with DAX so that it impacts just the sub-measure.

To explain why you are actually getting the result you expect with something similar to your Price Variance example:

Assume the Price Variance measure is defined as:

 

Price Variance =
VAR CY_Price = [CY Sales] / [QTY]
VAR PY_Sales =
    CALCULATE ( [CY Sales], SAMEPERIODLASTYEAR ( 'Date'[Date] ) )
VAR PY_Price = [PY Sales] / [PY Qty]
VAR Price_Variance = ( CY_Price - PY_Price ) * [QTY]
RETURN
    Price_Variance

 

Then assume we have a Calculation Group with a "YTD" Calculation Item:

 

CALCULATE (
    SELECTEDMEASURE (),
    DATESYTD ( 'Date'[Date] )
)

 

When you apply the YTD Calculation Item to Price Variance, this is what is effectively calculated:

 

Price Variance (YTD) =
CALCULATE (
    VAR CY_Price = [CY Sales] / [QTY]
    VAR PY_Sales =
        CALCULATE ( [CY Sales], SAMEPERIODLASTYEAR ( 'Date'[Date] ) )
    VAR PY_Price = [PY Sales] / [PY Qty]
    VAR Price_Variance = ( CY_Price - PY_Price ) * [QTY]
    RETURN
        Price_Variance,
    DATESYTD ( 'Date'[Date] )
)

 

 

Because the YTD Calculation Item applies a YTD filter to the original measure, all measures/expressions within the original measure inherit the new YTD filter.

 

You will get similar behaviour whenever a Calculation Item applies some sort of filter to SELECTEDMEASURE() via CALCULATE, and the original measure itself performs calculations that all respond intuitively to any filters applied.

 

Regards,

Owen


Owen Auger
Did I answer your question? Mark my post as a solution!
Blog
Twitter
LinkedIn

View solution in original post

2 REPLIES 2
OwenAuger
Super User
Super User

Hello @daxreport 

I think the part of the SQLBI article you're referring to is:

 

Because the [measure reference] replacement takes place only at the report level where the calculation groups are usually applied, it is not possible to propagate the replacement to measure references used in nested calculations. This behavior limits your ability to apply calculation groups only to a specific subexpression of a complex DAX calculation. 

 

My short explanation of this would be:

  • When Calculation Groups are used in the "usual" way, that is by adding a measure to a visual in a report and applying a filter on a particular Calculation Item, the measure used in the report is in its entirety replaced by the Calculation Item.
  • However, if you want to restrict the Calculation Item to apply just to a sub-measure or sub-expression within the definition of the measure used in the report, this cannot be done when Calculation Groups are used in the usual way.
  • In order to solve this issue, the author of the article shows how the model can be modified and the Calculation Item thena applied with DAX so that it impacts just the sub-measure.

To explain why you are actually getting the result you expect with something similar to your Price Variance example:

Assume the Price Variance measure is defined as:

 

Price Variance =
VAR CY_Price = [CY Sales] / [QTY]
VAR PY_Sales =
    CALCULATE ( [CY Sales], SAMEPERIODLASTYEAR ( 'Date'[Date] ) )
VAR PY_Price = [PY Sales] / [PY Qty]
VAR Price_Variance = ( CY_Price - PY_Price ) * [QTY]
RETURN
    Price_Variance

 

Then assume we have a Calculation Group with a "YTD" Calculation Item:

 

CALCULATE (
    SELECTEDMEASURE (),
    DATESYTD ( 'Date'[Date] )
)

 

When you apply the YTD Calculation Item to Price Variance, this is what is effectively calculated:

 

Price Variance (YTD) =
CALCULATE (
    VAR CY_Price = [CY Sales] / [QTY]
    VAR PY_Sales =
        CALCULATE ( [CY Sales], SAMEPERIODLASTYEAR ( 'Date'[Date] ) )
    VAR PY_Price = [PY Sales] / [PY Qty]
    VAR Price_Variance = ( CY_Price - PY_Price ) * [QTY]
    RETURN
        Price_Variance,
    DATESYTD ( 'Date'[Date] )
)

 

 

Because the YTD Calculation Item applies a YTD filter to the original measure, all measures/expressions within the original measure inherit the new YTD filter.

 

You will get similar behaviour whenever a Calculation Item applies some sort of filter to SELECTEDMEASURE() via CALCULATE, and the original measure itself performs calculations that all respond intuitively to any filters applied.

 

Regards,

Owen


Owen Auger
Did I answer your question? Mark my post as a solution!
Blog
Twitter
LinkedIn

Hello, @OwenAuger That is a very clear explanation. Better than SQLBI!! Thanks for your detailed response!

Helpful resources

Announcements
Europe Fabric Conference

Europe’s largest Microsoft Fabric Community Conference

Join the community in Stockholm for expert Microsoft Fabric learning including a very exciting keynote from Arun Ulag, Corporate Vice President, Azure Data.

Power BI Carousel June 2024

Power BI Monthly Update - June 2024

Check out the June 2024 Power BI update to learn about new features.

PBI_Carousel_NL_June

Fabric Community Update - June 2024

Get the latest Fabric updates from Build 2024, key Skills Challenge voucher deadlines, top blogs, forum posts, and product ideas.