how to convert mdx query to dax? - mdx

IIF(SUM
(
[Calendar].[Month].CurrentMember.Lag(17) :
[Calendar].[Month].CurrentMember,
[Measures].[Qty]
) = 0, 0,
SUM
(
[Calendar].[Month].CurrentMember.Lag(17) :
[Calendar].[Month].CurrentMember,
[Measures].[Local Num]
) /
SUM
(
[Calendar].[Month].CurrentMember.Lag(17) :
[Calendar].[Month].CurrentMember,
[Measures].[N Qty]
) )
I am trying to convert that mdx query to dax formula. is there any simple way to write dax formula for that mdx query?

If it is a measure you need, try this:
ValueLast17Months:=
CALCULATE
(
DIVIDE(SUM([Local Num]),SUM([N Qty])),
DATESINPERIOD
(
'Calendar'[Month],
MAX('Calendar'[Month]),
-17,
MONTH
)
)
If it was a calculated column you needed, this can work:
ValueLast17Months
= DIVIDE(
SUMX(
FILTER
(
'Calendar',
MONTH('Calendar'[Month]) + 17 >= MONTH(EARLIER('Calendar'[Month])) &&
MONTH('Calendar'[Month]) <= MONTH(EARLIER('Calendar'[Month]))
)
,[Local Num]
)
,
SUMX(
FILTER
(
'Calendar',
MONTH('Calendar'[Month]) + 17 >= MONTH(EARLIER('Calendar'[Month])) &&
MONTH('Calendar'[Month]) <= MONTH(EARLIER('Calendar'[Month]))
)
,[N Qty]
)
)

Related

DAX conditional measure errors out *Single Value for Column*

Sale Type is an attribute and is returning a Single Value error.
This expression works great in SQL but will not work here.
If ( [Sale Type] = "Upsell"
&& [Current Name] = "SaaS"
&& DATEDIFF ( [StartDate],[EndDate],Day ) + 1 > 364,
SUM ( [ARR] ),
SUM ( [TotalPrice] )
)

YTD Measure in DAX Studio doesn't show any value for several dates

Trying to calculate YTD for several dates in DAX STUDIO according to https://www.daxpatterns.com/time-patterns/ guide
I've created a measure in my model, which gets the job done when I use Date Dimension and calculates YTD for every date
CALCULATE (
[Sales Amt],
FILTER (
ALL ( 'Date' ),
'Date'[Year] = MAX ( 'Date'[Year] )
&& 'Date'[Date] <= MAX ( 'Date'[Date] )
)
)
But when I'm trying to reproduce the same result using DAX Studio, I get correct result only when I filter CALCULATETABLE for a certain date
This code works perfectly:
EVALUATE
CALCULATETABLE(
ADDCOLUMNS (
VALUES ( 'Date'[Date] ),
"YTD", CALCULATE (
[Sales Amt],
FILTER (
ALL ( 'Date' ),
'Date'[Year] = MAX ( 'Date'[Year] )
&& 'Date'[Date] <= MAX ( 'Date'[Date] )
)
)
)
,
'Date'[Date] = DATE(2018,5,1)
)
This code is expected to return YTD for every date in rows, but, unfortunately it doesn't. What am I doing wrong?:
EVALUATE
CALCULATETABLE(
ADDCOLUMNS (
VALUES ( 'Date'[Date] ),
"YTD", CALCULATE (
[Sales Amt],
FILTER (
ALL ( 'Date' ),
'Date'[Year] = MAX ( 'Date'[Year] )
&& 'Date'[Date] <= MAX ( 'Date'[Date] )
)
)
)
,
'Date'[Date] >= DATE(2018,5,1)
)
The only difference is = vs >=, but I get empty result for all the rows
Nothing is wrong with the way you defined your measure.
However, when testing the measure, you should try to write your DAX query in a way similar to what client tools like Power BI would do:
EVALUATE
SUMMARIZECOLUMNS(
'Date'[Date],
FILTER('Date', 'Date'[Date] >= DATE(2018,5,1)),
"YTD", CALCULATE (
[Sales Amt],
FILTER (
ALL ( 'Date' ),
'Date'[Year] = MAX ( 'Date'[Year] )
&& 'Date'[Date] <= MAX ( 'Date'[Date] )
)
)
)
or even better:
DEFINE MEASURE 'Sales'[Sales Amt YTD] = CALCULATE (
[Sales Amt],
FILTER (
ALL ( 'Date' ),
'Date'[Year] = MAX ( 'Date'[Year] )
&& 'Date'[Date] <= MAX ( 'Date'[Date] )
)
)
EVALUATE
SUMMARIZECOLUMNS(
'Date'[Date],
FILTER('Date', 'Date'[Date] >= DATE(2018,5,1)),
"YTD", [Sales Amt YTD]
)
The issue with the way you wrote it, using CALCULATETABLE, is that you create an outside filter context on the 'Date'[Date] column that contains all dates starting from 2018-05-01. When evaluating the YTD logic inside the FILTER statement, MAX('Date'[Year]) uses this filter context, so that it returns whatever year is the largest on your entire 'Date' table (for example 2025).
Remember, that the CALCULATE function only applies a context transition (row context to filter context) when evaluating the first argument. The filter arguments are evaluated on the original filter context.
If you want to stick with your syntax, you could write an additional CALCULATE to force the context transition to apply also to the 2nd argument of the inner CALCULATE call:
EVALUATE
CALCULATETABLE(
ADDCOLUMNS (
VALUES ( 'Date'[Date] ),
"YTD",
CALCULATE( // Additional CALCULATE to force context transition on filter arguments
CALCULATE (
[Sales Amt],
FILTER (
ALL ( 'Date' ),
'Date'[Year] = MAX ( 'Date'[Year] )
&& 'Date'[Date] <= MAX ( 'Date'[Date] )
)
)
)
),
'Date'[Date] >= DATE(2018,5,1)
)
This would be the same as referencing the measure directly, as referencing a measure always does an implicit CALCULATE:
EVALUATE
CALCULATETABLE(
ADDCOLUMNS (
VALUES ( 'Date'[Date] ),
"YTD", [Sales Amt YTD]
),
'Date'[Date] >= DATE(2018,5,1)
)

DAX - Last Value

I have this table
I would like to create measurement get the last traded value for each day. E.g.
How the DAX query should look like?
You have to create two measures. One for the last time in each date and another to get the value for that date and time.
Last Time :=
CALCULATE(MAX([Time]),FILTER('Table',[Date]=MAX([Date])))
Last Traded Value =
CALCULATE (
MAX ( 'Table'[Traded Value] ),
FILTER ( 'Table', [Date] = MAX ( [Date] ) && [Last Time] = [Time] )
)
Then add Date column to rows and Last Time and Last Traded Value measures to Values pane in a pivot table.
Let me know if this helps.
For example:
DEFINE
VAR TableTMP =
ADDCOLUMNS ( 'Table', "DateTime", [Date] + [Time] )
EVALUATE
SUMMARIZE (
NATURALINNERJOIN (
TableTMP,
SUMMARIZE (
GROUPBY ( TableTMP, [Date], "DateTime", MAXX ( CURRENTGROUP (), [DateTime] ) ),
[DateTime]
)
),
[Date],
[Time],
[Traded Value]
)
With the new window functions in DAX, I think this can be simplified to
Last Traded Value =
CALCULATE (
MAX ( 'Table'[Traded Value] ),
INDEX (
1,
ORDERBY ( 'Table'[Time], DESC ),
PARTITIONBY ( 'Table'[Date] )
)
)

DAX Measure - Summing up values between start-end dates in the same table

I have an "Assignments" Table like this:
Date End Date Allocation1111 Alex AA 11/20/2016 12/30/2016 0.52222 Eric BB 10/20/2016 11/30/2016 0.43333 John CC 10/20/2016 12/30/2016 12222 Eric DD 11/20/2016 1/1/2017 0.5
I also have a simple "Date" Table which DOES NOT have a relationship with the Assignments Table like this:
Date Month Month_Text Year Month-Year10/1/2016 10 Oct 2016 Oct-1610/2/2016 10 Oct 2016 Oct-1610/3/2016 10 Oct 2016 Oct-1610/4/2016 10 Oct 2016 Oct-16
Than I have the following DAX measure:
==============================
Sum of Assignments :=CALCULATE ( SUMX ( Assignments_Tbl, Assignments_Tbl[Allocation] ), FILTER ( VALUES ( Date_Tbl ), Date_Tbl[Date] >= MINX ( Assignments_Tbl, Assignments_Tbl[Start Date] ) && Date_Tbl[Date] <= MAXX ( Assignments_Tbl, Assignments_Tbl[End Date] ) )) * CALCULATE ( DISTINCTCOUNT ( Date_Tbl[Month] ), FILTER ( VALUES ( Date_Tbl ), Date_Tbl[Date] >= MINX ( Assignments_Tbl, Assignments_Tbl[Start Date] ) && Date_Tbl[Date] <= MAXX ( Assignments_Tbl, Assignments_Tbl[End Date] ) ) )
==============================
All seems OK when I have the Start Date and End Date as part of my Pivot Table like below:
Sum of Assignments in a pivot table with Start/End Dates
HOWEVER, if I remove the Start Date and End Date from the pivot table, the measure is calculating incorrectly and I can't find why.
For instance, as the pic below, the red circles show 0.9 for a person name "Eric" in in Oct-2016, instead of 0.4.
Sum of Assignments measure calculating incorrectly
I tried many things, but got stuck on this measure. Any idea?
After some deeper investigation, here is the proper measure:
New Measure =
SUMX (
Assignments_Tbl,
CALCULATE (
SUM ( Assignments_Tbl[Allocation] ) * DISTINCTCOUNT ( Date_Tbl[Month-Year] ),
FILTER (
VALUES ( Date_Tbl ),
Date_Tbl[Date] >= EARLIER ( Assignments_Tbl[Start Date], 1 )
&& Date_Tbl[Date] <= EARLIER ( Assignments_Tbl[End Date], 1 )
)
)
)

Restore original filter context in DAX formula

I have a data model with a table called Transactions (below), and TranDate which is the date dimension.
I have a measure to calculate the opening balance for the first date that is visible in the pivot table.
Op Bal First Selected :=
VAR MinDate = CALCULATE (
MIN ( TranDates[Tran Date] ),
ALLSELECTED ( TranDates )
)
RETURN
CALCULATE (
SUM ( Transactions[Amount] ),
FILTER
(
ALL ( TranDates ),
TranDates[Tran Date] < MinDate
)
)
If I deselect Jan-16, I get the desired result below:
However, the measure only works in Excel 2016 and not Excel 2013, because variables are not supported in Excel 2013. If I replace the MinDate variable with the DAX expression, then the measure will return blanks because ALLSELECTED restores the context in the FILTER() function and not the context in the CALCULATE() function (i.e. MinDate is 1-Jan instead of 1-Feb).
Is there an equivalent DAX formula that works in Excel 2013 / SSAS 2014 (i.e. without using variables)?
After lots of trial and errors, here's the measure I defined:
Op Bal First Selected:=
MINX
(
ADDCOLUMNS (
ADDCOLUMNS
(
SUMMARIZE (
ALL(Transactions),
Transactions[Tran Date]
),
"MinDate",
CALCULATE (
MIN ( Transactions[Tran Date] ),
ALLSELECTED()
)
),
"Op Bal First Selected Calc",
CALCULATE (
SUM ( Transactions[Amount] ),
FILTER
(
ALL( Transactions ),
Transactions[Tran Date] < [MinDate]
)
)
),
[Op Bal First Selected Calc]
)
I used ALL() in the inner context so that the original filter context (i.e. pivot table selection) is preserved in the context just outside of ALLSELECTED().
If you want to use the TranDate table as the filter, you can define it as follows:
Op Bal First Selected:=
MINX
(
ADDCOLUMNS (
ADDCOLUMNS
(
SUMMARIZE (
ALLSELECTED(TranDates),
TranDates[Tran Date]
),
"MinDate",
CALCULATE (
MIN ( TranDates[Tran Date] )
)
),
"Op Bal First Selected Calc",
CALCULATE (
SUM ( Transactions[Amount] ),
FILTER
(
ALL( TranDates ),
TranDates[Tran Date] < [MinDate]
)
)
),
[Op Bal First Selected Calc]
)