Forum Discussion
CALCULATE Challenge - Round 1
- 2 years ago
I think this should qualify, though it isn't super clean.
VAR _AllDates_ = SUMMARIZE ( ALL ( FactInternetSales ), Dates[Year], Dates[Date] ) VAR _DateRange_ = WINDOW ( 1, ABS, 0, REL, _AllDates_, ORDERBY ( Dates[Date] ), PARTITIONBY ( Dates[Year] ) ) VAR _Result = CALCULATE ( [Internet Sales], _DateRange_ ) RETURN _Result - 2 years ago
thank God it's such an obvious and easy solution that even a DAX novice could understand and doesn't rely on a function introduced within that last year which pretty much means the solution was unsolvable for 7 years or so...
WINDOW isn't required. A plain filter works fine too and has been around since the beginning.
VAR _AllDates_ = SUMMARIZE ( ALL ( FactInternetSales ), Dates[Date] ) VAR _CurrDate = MAX ( Dates[Date] ) VAR _CurrYear = YEAR ( _CurrDate ) VAR _DateRange_ = FILTER ( _ALLDates_, YEAR ( Dates[Date] ) = _CurrYear && Dates[Date] <= _CurrDate ) VAR _Result = CALCULATE ( [Internet Sales], _DateRange_ ) RETURN _ResultHowever, there are still 15 other date intelligence measures in the file that are part of the challenge.
I'm not really interested in doing all 15 other ones as I don't think they'll reveal much that this YTD example doesn't already. If there is one that you think is meaningfully different, let me know.
- 2 years ago
Greg_Deckler, PW is an easy case where the TI solution or something like the following is just as fast.
CALCULATE ( [Internet Sales], TREATAS ( VALUES ( Dates[Prior Week Date] ), Dates[Date] ) )
thank God it's such an obvious and easy solution that even a DAX novice could understand and doesn't rely on a function introduced within that last year which pretty much means the solution was unsolvable for 7 years or so...
WINDOW isn't required. A plain filter works fine too and has been around since the beginning.
VAR _AllDates_ = SUMMARIZE ( ALL ( FactInternetSales ), Dates[Date] )
VAR _CurrDate = MAX ( Dates[Date] )
VAR _CurrYear = YEAR ( _CurrDate )
VAR _DateRange_ =
FILTER (
_ALLDates_,
YEAR ( Dates[Date] ) = _CurrYear &&
Dates[Date] <= _CurrDate
)
VAR _Result = CALCULATE ( [Internet Sales], _DateRange_ )
RETURN
_Result
However, there are still 15 other date intelligence measures in the file that are part of the challenge.
I'm not really interested in doing all 15 other ones as I don't think they'll reveal much that this YTD example doesn't already. If there is one that you think is meaningfully different, let me know.
AlexisOlson A bit worse, a little over 50% without WINDOW but still within acceptable limits. I'll take the technique and apply it to the other 15 calculations and let you know if there is an issue. The interesting thing is that if you use a more traditional CALCULATE approach like below, the timing increases to nearly twice that of No CALCULATE:
Alexis Olson TYD CALCULATE 3 =
VAR _CurrDate = MAX ( Dates[Date] )
VAR _CurrYear = YEAR ( _CurrDate )
VAR _Result =
CALCULATE (
[Internet Sales],
FILTER (
SUMMARIZE ( ALL ( FactInternetSales ), Dates[Date] ),
YEAR ( Dates[Date] ) = _CurrYear &&
Dates[Date] <= _CurrDate
)
)
RETURN
_Result
The other interesting thing about this approach is that you are pretty much destroying the star schema or at least not leveraging it in the slightest. You effectively create a new table that includes all rows in the fact table summarized by Date and then create a filter clause over that. So this kind of says to me that the mantra of the star schema coupled with CALCULATE as being the silver bullet for all things DAX is effectively nonsense because you basically have to blow-up the star schema to get CALCULATE to function at any reasonable performance level.
Finally, I don't think it's intuitive that the SUMMARIZEd table includes all dates in it considering the filter context within a row within the table is to a specific date. That seems weird to me although I imagine it is because using SUMMARIZE against ALL of the fact table and then by Date brings all of those dates back into context somehow versus the individual date at the visual row.
- tamerj12 years ago
Community Champion
I would say that both Alex's solutions (WINDOW and SUMMARIZE) look more like a NoCALCULATE approach.
The only difference is replacingSUMX ( __TableVar, 'Table'[Column] )
with
CALCULATE ( SUM ( 'Table'[Column] ), __TableVar )
in fact once filter ALL ( 'Table' ) is used, CALCULATE remains there with absolutely no meaning of existence.
- Greg_Deckler2 years ago
Community Champion
tamerj1 Wow, hmm, there was that second rule. This formula (below) produces the same result as AlexisOlson's orignal which technically makes the CALCULATE superfluous. That said, the CALCULATE does not JUST wrap a function that would work without it so I think that going strictly by the rules specified Alexis' formula technically meets the specified criteria.
Alexis Olson TYD CALCULATE 4 = VAR _AllDates_ = SUMMARIZE ( ALL ( FactInternetSales ), Dates[Date] ) VAR _CurrDate = MAX ( Dates[Date] ) VAR _CurrYear = YEAR ( _CurrDate ) VAR _DateRange_ = FILTER ( _ALLDates_, YEAR ( Dates[Date] ) = _CurrYear && Dates[Date] <= _CurrDate ) VAR _Result = SUMX ( _DateRange_, [Internet Sales]) RETURN _Result