Parse a List to an MDX Query (List in MDX M Power BI) - mdx

I'm looking for a way to integrate a previously retrieved list as an input for a FILTER in a MDX query. I currently have the following code:
segment_var = Segment,
mdxQ = "SELECT
NON EMPTY ( { [Measures].[AMT] * [Forecast Type].[Forecast Type].[Forecast Level 2] } ) DIMENSION PROPERTIES MEMBER_NAME ON COLUMNS,
NON EMPTY ( {
[Period].[Year Month Name].[Name] *
[PL Spec].[PL Spec].[Level 6 Code].allmembers
} ) ON ROWS
FROM (
SELECT ( { [Forecast Type].[Current Indicator].&[Y] } ) ON COLUMNS
FROM (
SELECT ( { [PL Spec].[PL Spec].[Level 1 Code].&[101] } ) ON COLUMNS
FROM [AIR]))
WHERE (
FILTER([Management Structure - Segment].[Management Structure - Segment].[MS Level 5].ALLMEMBERS , [Management Structure - Segment].[Management Structure - Segment].currentmember.name=""" & segment_var & """))",
Segment on row 1 used to be a single value parameter but I want to use a list of segments (listSegment) as a reference instead so the result filters multiple segments. I've tried WHERE IN solutions but I can't seem to get it to work. Any help would be appreciated.
Error:
Expression.Error: We cannot apply operator & to types Text and List.

Try to generate segment_var as
{[Management Structure - Segment].[Management Structure - Segment].[1], [Management Structure - Segment].[Management Structure - Segment].[2], ...}

Managed to solve the issue in the following way:
Make the list of values to be filtered in the query
Transpose and combine the list using ", "
Convert to single variable
Code:
Convert =
Table.ToList(
Table.Transpose(
Table.FromList(#"Distinct")),
Combiner.CombineTextByDelimiter(", ")),
Var = List.First(Convert)

Related

is it possible to store a table into a DAX variable conditionally

I'd like to store a table in a variable, but based on conditions of the visual.
e.g.
VAR ColumnValues = values( SpecificTable[SpecificColumn] )
works fine, but what I'd like to do is:
VAR ColumnValues = if([some condition T/F], values( SpecificTable1[SpecificColumn1] ) , SpecificTable2[SpecificColumn2] )
For reference, this question is in exploration of workarounds to solve question: Dynamic measure that responds to dynamic dimension which I marked as answered prematurely. I still do not have a solution to dynamically work with column values in DAX.
I've not been able to work out a syntax that allows this. Switch only returns scalar strings, and IF seems to only allow for a scalar result, not a table. Any other options I'm not thinking of?
Was not explicitly using any condition, but the condition that I was checking for, that I was able to get the desired result with the following:
Create Field Parameter (name it "_Dimension"), selecting the columns that need to be in play in the DAX
DAX looks like this:
VAR SelectedDim = SELECTEDVALUE( _Dimension[_Dimension Fields] ) //fully qualified - created by field parameter
//stage the values in each of the columns available
VAR Dim1Values = ADDCOLUMNS( VALUES( Dim1[Column1] ) , "RowValue" , Dim1[Column1] , "ColumnName" , "'Dim1'[Column1]" )
VAR Dim2Values = ADDCOLUMNS( VALUES( Dim1[Column2] ) , "RowValue" , Dim1[Column2] , "ColumnName" , "'Dim1'[Column2]" )
//... same pattern, as many column as needed
VAR SelectedDimValues = FILTER( UNION( Dim1Values, Dim2Values ) , [RowValue] = SelectedDim ) //return the values just for the selected column
SelectedDimValues is a Variable that contains a table with the rows from my selected dimension.

trouble with dynamic year filter in MDX

I have the following query that I use in Azure data factory(this is on the source of a copy action):
SELECT
{ [Measures].[0INV_QTY],
[Measures].[0NET_VAL_S] }
ON COLUMNS,
NON EMPTY
{ [0CUST_SALES].[LEVEL01].MEMBERS *
[0SALESORG].[LEVEL01].MEMBERS *
[0COMPANY].[LEVEL01].MEMBERS *
[0MATERIAL].[LEVEL01].MEMBERS *
[ZDEBITOR].[LEVEL01].MEMBERS *
[0FISCPER].[LEVEL01].MEMBERS *
[0DEB_CRED].[LEVEL01].MEMBERS *
[0BILLTOPRTY].[LEVEL01].MEMBERS *
[0DOC_CATEG].[LEVEL01].MEMBERS *
[0SHIP_TO].[LEVEL01].MEMBERS }
DIMENSION PROPERTIES
[0SALESORG].[20SALESORG],
[0COMPANY].[20COMPANY],
[0CUST_SALES].[80CUST_SALES],
[0CUST_SALES].[20CUST_GRP1],
[0CUST_SALES].[20PMNTTRMS],
[ZDEBITOR].[20CRED_LIMIT],
[0MATERIAL].[20MATERIAL],
[0DEB_CRED].[20DEB_CRED],
[0BILLTOPRTY].[20BILLTOPRTY],
[0DOC_CATEG].[20DOC_CATEG],
[0SHIP_TO].[20SHIP_TO],
[0FISCPER].[80FISCPER]
ON ROWS
FROM $0SD_C03
WHERE ({[0CALYEAR].[2020], [0CALYEAR].[2021], [0CALYEAR].[2018], [0CALYEAR].[2019]})
In here I would like to replace the WHERE with something like Cast(YEAR(GETDATE())-4 as varchar(10)) Now I am really new to MDX and I keep getting stuck. Could anyone point me in the right direction?
So what i want to achieve is not having to adjust the query every year and be able to only have the last 4 years.
If you are looking for a SQL equivalent as below in MDX
SELECT ... From ... WHERE date > DATEADD(year,-4,GETDATE())
Try using "with member" and function parallelperiod.
CREATE MEMBER CurrentCube.Measures.[Last4Years] AS
ParallelPeriod( [Date].[Date].[Date Yr], 4, StrToMember(“[Date].[Date].&[” + Format(now(), “yyyyMMdd”) + “]”))
: StrToMember(“[Date].[Date].&[” + Format(now(), “yyyyMMdd”) + “]”)
;

The expression specified in the EVALUATE statement is not a valid table expression

I'm working on a Tabular cube in Visual Studio.
I have a DAX formula in the cube that works fine:
SUMX(FILTER(factFHA, factFHA[EventCd]="D"), [LoanCount])
When I run it in SSMS as:
evaluate(
SUMX(FILTER(factFHA, factFHA[EventCd]="D"), [LoanCount])
)
it fails with following error:
Query (1, 1) The expression specified in the EVALUATE statement is not a valid table expression.
I have 2 other formulas that both work fine:
evaluate(factFHA)
evaluate(filter('factFHA', [EventCd] = "D"))
I can't figure out what is wrong with the SUMX with FILTER
Please advise. Thank you.
EVALUATE function only works if you pass a table or an expression that returns a table, you are passing a SUMX function which return a scalar value (Decimal).
The syntax to write queries using DAX, is as follows:
[DEFINE { MEASURE <tableName>[<name>] = <expression> } -> Define a session (optional) measure
EVALUATE <table> --> Generate a table using your measures or creating calculated columns
[ORDER BY {<expression> [{ASC | DESC}]}[, …] --> Order the returned table by a passed column or expression
[START AT {<value>|<parameter>} [, …]]] --> This is an ORDER BY Sub-clause to define from which the query results will start.
Define your measure then use then use it inside the EVALUATE clause using a expression that evaluates to a table.
DEFINE
MEASURE factFHA[MyMeasure] =
SUMX ( FILTER ( factFHA, factFHA[EventCd] = "D" ), [LoanCount] )
EVALUATE
( SUMMARIZE ( FILTER ( factFHA, factFHA[EventCd] = "D" ), factFHA[AnyColumnToGroup]
, "Sum of MyMeasure", SUM ( factFHA[MyMeasure] ) ) )
Let me know if this helps.

Mdx Query Show Year Level Data for all years except This Year

SELECT
NON EMPTY
{[Measures].[AMOUNTCUR]} ON 0
,NON EMPTY
{
NULL : [PRX_UE_DATE].[Calender].[Year].&[2015]
,[PRX_UE_DATE].[Calender].[Year].&[2017]
,Descendants
(
[PRX_UE_DATE].[Calender].[Year].&[2016]
,[PRX_UE_DATE].[Calender].[Month]
)
} ON 1
FROM [PRX_SalesDataModel];
I have a query like above. It's working It returns 2016 on month based others years are year based.
Now I have to add more dimensions on this mdx but when i try it to like
SELECT
NON EMPTY
{[Measures].[AMOUNTCUR]} ON 0
,NON EMPTY
{
NULL : [PRX_UE_DATE].[Calender].[Year].&[2015]
,[PRX_UE_DATE].[Calender].[Year].&[2017]
,
Descendants
(
[PRX_UE_DATE].[Calender].[Year].&[2016]
,[PRX_UE_DATE].[Calender].[Month]
)
*
[PRX UE CLIENT].[SEGMENTID].ALLMEMBERS
} ON 1
FROM [PRX_SalesDataModel];
I get error Members, tuples or sets must use the same hierarchies in the function.
You just need to keep all the date dimension stuff in set braces {...}:
SELECT
NON EMPTY
{[Measures].[AMOUNTCUR]} ON 0
,NON EMPTY
{
NULL : [PRX_UE_DATE].[Calender].[Year].&[2015]
,[PRX_UE_DATE].[Calender].[Year].&[2017]
,
Descendants
(
[PRX_UE_DATE].[Calender].[Year].&[2016]
,[PRX_UE_DATE].[Calender].[Month]
)
}
* [PRX UE CLIENT].[SEGMENTID].ALLMEMBERS
ON 1
FROM [PRX_SalesDataModel];
You could even make it maybe more readable by moving the date stuff into a named set via a WITH clause:
WITH SET [DatesSet] AS
{
NULL : [PRX_UE_DATE].[Calender].[Year].&[2015]
,[PRX_UE_DATE].[Calender].[Year].&[2017]
,
Descendants
(
[PRX_UE_DATE].[Calender].[Year].&[2016]
,[PRX_UE_DATE].[Calender].[Month]
)
}
SELECT
NON EMPTY
{[Measures].[AMOUNTCUR]} ON 0
,NON EMPTY
[DatesSet]
* [PRX UE CLIENT].[SEGMENTID].ALLMEMBERS
ON 1
FROM [PRX_SalesDataModel];
You've got your answer from #whytheq on why the error cropped up. There is just one part which I felt is not handled yet. You are building the set of years by hand. Instead of that, it can be made dynamic like below -
with set AllYearsExceptCurrent as
filter(
[PRX_UE_DATE].[Calender].[Year].members as yr,
yr.current.item(0).member_value <> Format(Now(), "yyyy")
)

MDX Date Formatting

Can any one please tell me how to format date in MDX queries? We dont use SSRS to generate report ,we have our own customised reporting tool built on SSAS.Date filter sends date in yyyy/mm/dd format . As of now we dont have a date dimension. My date member looks like:
[CNB_DimSampleInfo].[COAReleasedON].&[2013-01-02T03:20:00].
How can I format date in STRTOmemeber? I have tried doing this. My question is how will the value coming from user suit my member format as below. I know ssrs does it easily but we are not using SSRS. Below is my Code
my code
SELECT
[Measures].[Result] ON COLUMNS
,NON EMPTY
{
[CNB_DimProduct].[ProductUcode].[ProductUcode].ALLMEMBERS*
[CNB_DimProduct].[ProductDesc].[ProductDesc].ALLMEMBERS*
[CNB_DimTest].[TestUcode].[TestUcode].ALLMEMBERS*
[CNB_DimTest].[TestName].[TestName].ALLMEMBERS*
[CNB_DimSampleInfo].[LotNo].[LotNo].ALLMEMBERS*
[CNB_DimSampleInfo].[BatchNo].[BatchNo].ALLMEMBERS*
[CNB_DimSampleInfo].[COAReleasedBy].[COAReleasedBy].ALLMEMBERS*
[CNB_DimSampleInfo].[COAReleasedON].[COAReleasedON].ALLMEMBERS*
[CNB_DimSampleInfo].[SampleReferenceNo].[SampleReferenceNo].ALLMEMBERS*
[CNB_DimSampleInfo].[AnalysedBy].[AnalysedBy].ALLMEMBERS*
[CNB_DimSampleInfo].[AnalysedOn].[AnalysedOn].ALLMEMBERS
} ON ROWS
FROM
(
SELECT
StrToMember
(
"[CNB_DimSampleInfo].[COAReleasedON].[" + Format("2013-01-02","yyyy MM")
+ "]:STRTOMember([CNB_DimSampleInfo].[COAReleasedON].["
+
Format
("2013-01-02"
,"yyyy MM"
)
+ "]"
) ON COLUMNS
FROM Cube001
);
There is also StrToSet which is better in your circumstance as you're using the : operator which returns a set:
...
...
FROM
(
SELECT
StrToSet
(
"[CNB_DimSampleInfo].[COAReleasedON].[" + Format("2013-01-02","yyyy MM")
+ "]:[CNB_DimSampleInfo].[COAReleasedON].["
+
Format
("2013-01-02"
,"yyyy MM"
)
+ "]"
,CONSTRAINED
) ON COLUMNS
FROM Cube001
);
does the following definitely return the date formatted the same as your key values?
Format("2013-01-02","yyyy MM")
Do your key values for dates look like this?...
[CNB_DimSampleInfo].[COAReleasedON].[2013 01]
Your date member
[CNB_DimSampleInfo].[COAReleasedON].&[2013-01-02T03:20:00]
looks like a bad candidate for a user date parameter, as it's precise down to the minute (perhaps the second). Unless the user exactly matches the time, they'll get nothing. But perhaps you're enforcing exact matches by using a LimitToList select list in the UI.
To get this member name, you can format the input string like this:
format([Your Input Parameter],'yyyy-MM-ddThh:mm:ss')
I have tried out using filter as below
SELECT
[Measures].[Result] ON COLUMNS
,NON EMPTY
{
filter([CNB_DimSampleInfo].[COAReleasedON].members,instr([CNB_DimSampleInfo].[COAReleasedON].currentmember.member_caption,"2013-01-02")>0 or instr([CNB_DimSampleInfo].[COAReleasedON].currentmember.member_caption, "2013-04-01")>0)
*[CNB_DimProduct].[ProductUcode].[ProductUcode].ALLMEMBERS*
[CNB_DimProduct].[ProductDesc].[ProductDesc].ALLMEMBERS*
[CNB_DimTest].[TestUcode].[TestUcode].ALLMEMBERS*
[CNB_DimTest].[TestName].[TestName].ALLMEMBERS
} ON ROWS
FROM Cube002