cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
CloudMonkey Post Patron
Post Patron

Cumulative total query

Hi,

 

I know the following formula works to find the cumulative total but I don't fully understand how it works:

 

[CumulativeProducts] :=
CALCULATE (
    SUM ( Sales[Quantity] ),
    FILTER (
        ALL ( 'Date' ),
        'Date'[Datekey] <= MAX ( 'Date'[Datekey] )
    )
)

I'm reading the 'definitive guide to dax'. It says the MAX section means "the maximum value of DateKey in the current context". And that "because the expression of part of the CALCULATE filters, it still works in the original filter context".

 

What I don't understand is why would the original filter context apply if we are using the "ALL ('Date')" function? Why doesn't MAX('Date'[Datekey']) return the maximum in the whole date table?

 

Does the FILTER section return all rows of the Date table and then CALCULATE further reduces those rows to the existing filter context? If so how does CALCULATE know to ignore dates greater than current filter context's date, but not to ignore dates less than the current filter context's date?

 

Thanks for any help,

 

CM

1 ACCEPTED SOLUTION

Accepted Solutions
Super User III
Super User III

Re: Cumulative total query

I actually went through on some of my own data to create a cumulative total in this manner (since the example given is not exactly the way I would do it) and I think the example might be wrong.  Have you actually implemented this cumulative total on the sample data they provide? I would be interested if it does work.  I'm sure there's some way to do it the way they say using RELATED, but when I started from scratch, I ended up with this:

Cumulative Amt = CALCULATE(SUM('Sales'[Quantity]), FILTER(ALL('Sales'), 'Sales'[Date] <= MAX('Sales'[Date]) ))


The big difference is that I'm not filtering the Date table, I'm filtering the Sales table. However, I think this example is still an example of what you find confusing.  There's nothing special about the MAX function. It could be FIRSTNONBLANK, SELECTEDVALUE, MIN, or any other expression that defines what the "previous" values for the cumulative total are.  What is special is the FILTER function.  

 

The filter expression is actually iterated against every row in the table (in this case ALL('Sales')) to see if it evaluates to true.  It's checking that for each row the 'Sales'[Date] is less than or equal to the value of "MAX('Sales'[Date])".  It's my understanding that because your MAX expression doesn't have a new context explicitly defined, it evaluates once at a level out, essentially evaluating against the data before the ALL is applied.  

I've looked over documentation to see if there's anywhere that the context switch is explicitly called out, or articles that explain it, but I can't seem to find any.  I've never questioned it, because how else would you be able to filter a table based on a current value? The automatic context switching is incredibly useful and feels natural to me, so I feel like I can't explain further.  Maybe somebody like @marcorusso or @Greg_Deckler might be able to give a better explanation on how this works.

View solution in original post

4 REPLIES 4
Super User III
Super User III

Re: Cumulative total query

So this works because you have your dates and Sales data in different tables.

The first part of the CALCULATE expression is easy.  You want the sum of all values in Sales[Quantity].

 

The second part is creating the filter.  Any filters applied here override current filters.  However, this is only overriding filters on the 'Date' table.  So what happening is the FILTER is starting with ALL 'Date' values, and then filtering to only return rows where the [Datekey] is <= MAXimum [Datekey].  The trick here is that MAX('Date'[Datekey]) is operating at the original context, while defining the new context. 

So this will keep any filters from other tables (like Sales category), but it will return all values where the date is earlier than the current context's date.

 

Dealing with headaches like this, where you're not sure why MAX(Datekey) works, is why I prefer to use SELECTEDVALUE instead of MAX.  It returns a blank if you don't have a single selection for that value, and works perfectly when your context is correct.

CloudMonkey Post Patron
Post Patron

Re: Cumulative total query

Thanks @Cmcmahan 

 

Why does 'Date'[Datekey] operate in the new context but MAX('Date'[Datekey]) operate in the original context? Is there something special about the MAX function?

 

Thanks,

 

CM

Super User III
Super User III

Re: Cumulative total query

I actually went through on some of my own data to create a cumulative total in this manner (since the example given is not exactly the way I would do it) and I think the example might be wrong.  Have you actually implemented this cumulative total on the sample data they provide? I would be interested if it does work.  I'm sure there's some way to do it the way they say using RELATED, but when I started from scratch, I ended up with this:

Cumulative Amt = CALCULATE(SUM('Sales'[Quantity]), FILTER(ALL('Sales'), 'Sales'[Date] <= MAX('Sales'[Date]) ))


The big difference is that I'm not filtering the Date table, I'm filtering the Sales table. However, I think this example is still an example of what you find confusing.  There's nothing special about the MAX function. It could be FIRSTNONBLANK, SELECTEDVALUE, MIN, or any other expression that defines what the "previous" values for the cumulative total are.  What is special is the FILTER function.  

 

The filter expression is actually iterated against every row in the table (in this case ALL('Sales')) to see if it evaluates to true.  It's checking that for each row the 'Sales'[Date] is less than or equal to the value of "MAX('Sales'[Date])".  It's my understanding that because your MAX expression doesn't have a new context explicitly defined, it evaluates once at a level out, essentially evaluating against the data before the ALL is applied.  

I've looked over documentation to see if there's anywhere that the context switch is explicitly called out, or articles that explain it, but I can't seem to find any.  I've never questioned it, because how else would you be able to filter a table based on a current value? The automatic context switching is incredibly useful and feels natural to me, so I feel like I can't explain further.  Maybe somebody like @marcorusso or @Greg_Deckler might be able to give a better explanation on how this works.

View solution in original post

louisvp Helper II
Helper II

Re: Cumulative total query

Dear Community, I want to create a simular table but then in Power Query using the m Query language. Could someone help me with this? When I use the DAX code in Power BI Desktop, my Desktop file beocomes very slowly: Running total size = CALCULATE ( COUNTA (Data [StaffLevelName]), FILTER ( ALL (Data) , Data [FiscalStartYear] <= MAX (Data [FiscalStartYear])) ) Thank you very much. Kind regards Louis van Paassen

Helpful resources

Announcements
New Ranks Launched March 24th!

New Ranks Launched March 24th!

The time has come: We are finally able to share more details on the brand-new ranks coming to the Power BI Community!

‘Better Together’ Contest Finalists Announced!

‘Better Together’ Contest Finalists Announced!

Congrats to the finalists of our ‘Better Together’-themed T-shirt design contest! Click for the top entries.

Arun 'Triple A' Event Video, Q&A, and Slides

Arun 'Triple A' Event Video, Q&A, and Slides

Missed the Arun 'Triple A' event or want to revisit it? We've got you covered! Check out the video, Q&A, and slides now.

Top Solution Authors
Top Kudoed Authors