Using a date range in calculated member in MDX query for Tabular cube model - ssas

I have a requirement where I have to get the values of different measure with each measure having its own date range, the following query works and gets me the data over an year,
WITH MEMBER [Measures].[Ex1] AS ([Measures].[Average Spending], [Date].[Year].&[2020])
MEMBER [Measures].[Ex2] AS ([Measures].[Average Time Spent], [Date].[Year].&[2019])
SELECT {[Customer].[Name].[Name]} ON 1, {[Measures].[Ex1],[Measures].[Ex2]} ON 0 FROM [Model];
but when I try to pass a date range instead of year, I'm getting an error,
WITH MEMBER [Measures].[Ex1] AS ([Measures].[Average Spending], [Date].[Year].&[2020])
MEMBER [Measures].[Ex2] AS ([Measures].[Average Time Spent], [Date].[Date].[01-May-2020]:[Date].[Date].[31-May-2020])
SELECT {[Customer].[Name].[Name]} ON 1, {[Measures].[Ex1],[Measures].[Ex2]} ON 0 FROM [Model];
I'm getting the following error,
Executing the query ... The function expects a string or numeric
expression for the argument. A tuple set expression was used. Run
complete
How do I get the measure for a date range for each calculated member?

If you do not use a tuple (i. e. a combination of single members of the hierarchies like Measures or Year), but a set, then you need to tell MDX what to do with the set elements to get to a single value. I would assume the following will give what you want:
WITH
MEMBER [Measures].[Ex2] AS
Aggregate([Date].[Date].[01-May-2020]:[Date].[Date].[31-May-2020],
[Measures].[Average Time Spent]
)
...
Instead of Aggregate, you could also use Sum, Avg, Variance etc. but normally, I prefer using Aggregate, as this uses whichever aggregation method is defined for the measure in the cube, i. e. it is more universal, and the query does not need to be adapted to changes in the cube calculation scripts.
See also Aggregate in the SSAS documentation

Related

SSAS Cube Calculated Member infinity Totals value

I'm working on Power BI with a live connection SSAS cube. I have two dimension tables, Customer and Year and a fact table. I want to generate a report which shows the proportion of sales amount by citizenship for each Year. I used this MDX expression on SSAS Cube to create a new calculated member.
(([Year].[Year].currentmember,[Dim Customer].[Cittzenship].currentmember),[Measures].[Totale Sales]) /([Cittzenship].currentmember.parent,[Measures].[Totale Sales])
The result of the query works as expected but on power BI report table the total value is infinity.
Result
I'm stuck solving this problem. I would love if somebody guide me how to solve this.
The reason is probably that for the totals, the parent does not exist, and hence, its value is replaced by null for the calculation. In most contexts, SSAS replaces null by 0, and hence the division is by 0, which mathematically is infinity. What you can do is use the Divide function instead of /, which is exactly meant for this purpose, as it delivers the same result as /, except if the divisor is zero, in which case it delivers null.
By the way: Divide was introduced in SSAS 2012, so if you are not on that version at least, you would have to use a construct like IIf(divisor <> 0, dividend / divisor, null), which is exactly how Divide(dividend, divisor) is defined. Like I said
above, in MDX in contrast to SQL, comparing to 0 also implicitly compares to null.

Create MDX to Divide two measures for each month and then sum the all of the months

I have a multidimensional cube that needs a custom measure that I'm not sure how to build.
That data looks like this:
MemberID-----Date-------EventType
1--------------1/1/2016-------1
2--------------1/1/2016-------2
3--------------2/1/2016-------1
2--------------2/1/2016-------2
4--------------2/1/2016-------2
There is a count measure in the cube, but others can be added if needed. I need to create a measure that will use whatever filters the user applies and then count the EventType (1 and 2 only) by month, divide the resulting counts for EventType 1 into the count for EventType 2 (for each month individually), and finally sum the monthly results. For example 1/1/2016 would be 1/1=1 (count of EventType 1 and count of EventType 2) and 2/1/2016 would be 1/2=0.5 so the resulting measure value for the two months would be 1+0.5=1.5. Any help is greatly appreciated.
Let's assume you have a Date dimension with an attribute called Month. And let's assume you have an EventType dimension. And let's assume you have a count measure in your measure group called Cnt. Here's what else you need to do.
First, go to the DSV and add a new calculated column to the fact table which is called NullInt and is the following expression:
cast(null as int)
Then create a new Sum measure in your measure group off that column and call the measure My Rollup. Under the Source property, change NullHandling to Preserve so that it will start off null.
To explain why we're doing this, a scoped assignment to a physical measure will aggregate up. (If you assign a value to a physical measure at the grain of each month, then it will rollup to the grand total.) But a scoped assignment to a calculated measure doesn't roll up.
Then in your MDX script add the following calculations:
scope([Date].[Month].[Month].Members); //calculate at the month level then rollup
[Measures].[My Rollup] = DIVIDE(
([Event Type].[Event Type].&[1],[Measures].[Cnt]),
([Event Type].[Event Type].&[2],[Measures].[Cnt])
);
end scope;
Note that your version of SSAS probably has the DIVIDE function if it's AS2012 with the latest service pack or newer. But if it doesn't, you can always do division the old fashioned way as IIF(denom=0,null,num/denom).

MDX expressions to aggregate data at certain level for calculated member

For now sometimes I have problems with creating difficult calculated members in SSAS. Is it possible to make case which will SUM certain measure on certain level when user choose another certain level of dimension? For example we have standard time dimension with 4 levels:
Year
Month
Week
Day
Also we have some measure orders which have default function SUM in properties.
Which case do we need to calculate this: sum all orders in week which including current day which we have chosen already.
Also could you recommend me some nook or source for level up my mdx knowledge?
Thanks a lot.
Yes, it's possible, when you use MDX functions, which are connected with levels.
Here is an example with Year > Quarter > Month > Day hierarchy:
Use MDX calculated member to have a SUM of upper level member children (including selected one):
The same if you want to create calculation inside the cube:
CREATE MEMBER CURRENTCUBE.[Measures].[SameLevelMembers]
as SUM({[Report Date].[Report Date].CurrentMember.Parent.Children},[Measures].[Count]),
VISIBLE = 1 ;
And a result in cube browser:
Hundreds of articles you can find there: http://ssas-wiki.com/w/Articles#MDX
I also like this one: http://mdxpert.com because of well-structured info.

How to filter time hierarchy based on anothr attribute's value in MDX

I want to create a calculated member. I have a time dimension hierarchy" YQM", which has Year/Quarter/Month. The calculated member should find YTD till the current month. However, the value of current month will come from database.
I have created a attribute, "CP" which returns the current month value.
Please tell me how to create the calculated member. Please note "CP" is not in the same hierarchy YQM.
I don't understand why you are using Aggregate. So, I will assume that it is there for some purpose, which you have't clarified. Now, if the members of [YQM].[Month] and [Dim].[CP] are of the same format, then you can try the code below:
Aggregate(
PeriodsToDate([Dim].[YQM].[Month].MEMBERS,
FILTER([Dim].[YQM].[Month].MEMBERS,
[YQM].[Month].CURRENTMEMBER.member_value = [Dim].[CP].FirstChild.member_value)
)
)
Why not try playing with the function YTD. The following should give you the monthly amount in the first column of data and then the YTD amount in the next column:
WITH MEMBER [Measures].[YearToDate] AS
AGGREGATE(
YTD()
,[Measures].[someMeasureInCube]
)
SELECT
{
[Measures].[someMeasureInCube],
[Measures].[YearToDate]
} ON 0,
[Dim].[YQM].[Month].MEMBERS ON 1
FROM [yourCube]

mdx datediff error

select measures.name on 0,
datediff("d", [Fecha].[Date].currentmember.member_value, [Dim Date].[Date].currentmember.member_value) on 1
from cube
Error: Execution of the managed stored procedure datediff failed with
the following error: Exception has been thrown by the target of an
invocation.Argument 'Date1' cannot be converted to type 'Date'
Is there any requirements to do datediff in mdx?
In the dimension these member are defined as datetime, not sure if this influence in anyway the result...
Update: I solved the problem by making the calculation at the datasource view and at the cube I added a measure that I could use in MDX to create the indicator that I needed. Of course this is all using SSAS for testing the result and SSDT for creating the members. I hope this approach helps a lot of people even though i don't know if this is the best case scenario. Happy MDX ;)
By default, the axis will show, not the member_value, but the member name, which is always a string. The Member_Value is a measure.
With Member MyDateDiff as
datediff("d", [Fecha].[Date].currentmember.member_value, [Dim Date].[Date].currentmember.member_value)
Select
(Measures.MyDateDiff, Measures.Name) on 0
(Fecha.Date.Members, [Dim Date].[Date].Members) on 1
From cube
EDIT
I'm still new to this too, but after your comments, I thought I should elaborate on the process I went through to get similar queries right.
First, make sure you are getting the data you think you are. Get those Member_Value measures into the Columns dimension:
With
Member FechaDate as
[Fecha].[Date].currentmember.member_value
Member MyDate as
[Dim Date].[Date].currentmember.member_value
Select
(Measures.FechaDate, Measures.MyDate) on 0
(Fecha.Date.Members, [Dim Date].[Date].Members) on 1
From cube
Are you getting date values? If yes, try out your datediff function. If not, check the dimension definitions. I wouldn't be surprised to find the the ValueColumn of one of your attributes was set to the key field instead of the date value field, or some such thing.
You may need two steps, but the date add method should be fine. The Member approach from Bill is good, but it returns it as a string, not a date object. If it's in the correct format, you should be able to do:
Member MyDate as
DATEDADD("d", 1, VBAMDX!CDate([Dim Date].[Date].currentmember.member_value))
Depending on how your date string ends up formatted, you may have a little more work to do.