MDX IIF statement to calculate new member basing on measure and hierarchy leaves - ssas

I have a simple Data Cube for computing shared expenditures with one measure Amount and some dimensions and hierarchies but interesting one would be Relationship. It describes who bought something for whom. It's structure is:
Who
For whom
Relationship key
I am trying to code a calculation representing debt. For example if I bought something for sharing usage it would be half of 0.5 * Amount. On the other hand, if I bought something for myself it would be 0 * Amount.
As far I tried following calculation:
IIF(
[dimRelationship].[Relationship].currentMember = [dimRelationship].[Relationship].[RelatonshipID].&[MeShared],
[Measures].[Amount]*0.5,
[Measures].[Amount]*0)
It works good only at lowest RelationshipID level. When I roll-up browsered pivot-table it is acting according to else-expression. That is not really surprising because hierarchy's currentMember is not MeShared anymore. Another bad thing that total aggregation work neither - it would be most important as a general summary. Is there any suffix like .LeafMember or something like that which could help me perform this calculation?
Thank you in advance!
Best regards,
Max!

In you fact table add another column, in this column store the "Amount" multiplied by the relationshipID for that particular row. This will address you issue right out the box

Try SCOPE statement.
Firstly, create new calculation [Debt Calculation] as [Measures].[Amount]*0 /* as ELSE-scenario */
Then create a SCOPE:
SCOPE([Debt Calculation],[dimRelationship].[Relationship].[RelatonshipID].&[MeShared]);
THIS=[Measures].[Amount]*0.5;
END SCOPE;
If it's the lowest level of hierarchy and is a dimension key (which is used as a link to measure groups), it will re-calc higher levels of this dimension automatically. Please post a result here if not.

Related

Is there any ways to dynamic cumulative measure in MDX?

All of the measure that I want to cumulative has the same formula. So, is there any way to use the thing like function or any thing in calculate measure to resolve this issue?
There are two ways to achieve your aim:
1- the first solution is based on using the business intelligence wizard to add time intelligence to your solution.
The time intelligence enhancement is a cube enhancement that adds time calculations (or time views) to a selected hierarchy. This enhancement supports the following categories of calculations:
List item
Period to date.
Period over period growth.
Moving averages.
Parallel period comparisons.
The wizard will let you chose the calculations and measures you want to apply.
Visit : https://learn.microsoft.com/en-us/analysis-services/multidimensional-models/define-time-intelligence-calculations-using-the-business-intelligence-wizard
Visit : http://www.ssas-info.com/analysis-services-articles/62-design/2465-ssas-time-intelligence-wizard
2- Use a dimension table to calculate your calculations, this solution is more complicated, but very powerful and one of the best practices.
The first step is to create a new physical dimension, with real
members for each of the calculations we're going to need. We don't
actually need to create a table in our data warehouse for this
purpose, we can do this with an SQL view like this
CREATE VIEW DateTool AS SELECT ID_Calc = 1, Calc = 'Real Value' UNION ALL SELECT ID_Calc = 2, Calc = 'Year To Date'
Next, we need to add this view to our DSV and create a dimension based
on it. The dimension must have one hierarchy and this hierarchy must
have its IsAggregatable property set to False. The DefaultMember
property of this hierarchy should then be set to the Real Value
member. Giving this dimension a name can be quite difficult, as it
should be something that helps the users understand what it does –
here we've called it Date Tool. It needs no relationship to any
measure group at all to work.
Our next task is to overwrite the value returned by each member so
that they return the calculations we want. We can do this using a
simple SCOPE statement in the MDX Script of the cube:
this code let you create the YEAR-TO-DATE aggregation for all your measures.
SCOPE ([Date Tool].[Calculation].[Year To Date]); THIS = AGGREGATE ( YTD ([Date Order].[Calendar].CurrentMember), [Date Tool].[Calculation].[Real Value]); END SCOPE;
Visit:https://subscription.packtpub.com/book/big_data_and_business_intelligence/9781849689908/6/ch06lvl1sec35/calculation-dimensions

SSAS OLAP Cube - Sum measure only works when keys are present

(This is a mock of my actual setup to help me figure out the problem.)
I have one fact table and one dimension table, linked by an id field.
My goal is to make a measure that sums up all "thing_count" (integer) values in my cube.
If the user splits by nothing, it should show the total "thing_count" for all records in the fact table. If it's split by "category_name" from the dimension, it should show the total "thing_count" for each category.
I tried to achieve this by creating a SUM measure in my cube:
It works, but not in the way I intend it to
It always shows (null) unless I drag in the "id" field from the dimension.
Measure only:
Measure and category:
Measure, category, and id:
How can I make the measure show the value without keys needing to be present?
Edit:
For GregGalloway's request (I've edited the names so the screenshots are easier to follow):
One common explanation for this behavior (no aggregation) is that you have inadvertently commented out the CALCULATE; statement in your MDX script in the cube. Please check that statement is still present.

Showing measure values as "not applicable" which are not related to dimensions

I have a requirement where report should show measures as "not applicable" if one selects a attribute which is not linked to that measure Group.
1) unrelateddimesnion= 'false' is not solving my problem because i have few default members.
2) I could able to show measure value as "not applicable " by Writing this MDX statement
([Customer].[customer name].[customer name], [measures].[sales forecast]) = 'not applicable'
but with this i have to repeat the same line for each and every attribute present in the dimension ( and also for each and every measure present in the measure Group)
can someone help me Writing the MDX for entire dimension instead for individual attribute. Thanks in advance.
Kind Regards
Mah
Bad news! An MDX script on your cube can't reference such a sub-cube in a simple way. You may have seen the LEAVES(dimension) function for a scope statement but that won't work when one attribute in a dimension has the [All] level and another has a selection. (That is to say the function returns the leaves of the dimension's key attribute). What you can do is use nested scope statements with the outer one filtering down to the list of measures you want to affect. That will at least save you typing a formula num_attributes * num_measures times. The scope statement may even accept the MEASUREGROUPMEASURES function. (When I last used that it only returned visible measures but that's probably what you want anyway.)
It may be easier to link measure group and dimension and let your data sit on the UNKNOWN member. (Or an explicit dummy member.) Then filters against or slices to real customer hierarchy values will exclude your [Sales Forecast] rows and show it as null. That's not something I've done and it'll have ramifications for error processing and you'll have to allow users sight of the unknown or dummy member. So recommend you play with the idea before you rely on it.
I hope this helps some.

Calculated Members with multiple Attribute Hierarchy - MDX

I found this little code where it dynamically calculates TOTALs for all Dimension/Hierarchy I want.
This is close to what I need but will not work for Dimensions that have different number of Hierarchy Levels (Attribute Hierarchy). Current Code only works if there is only one Attribute Hierarchy because of CurrentMember.Parent. I could use CurrentMember.Parent.Parent for Dimension.Hierarchy that have two levels and so on but would not work for the the ones with only one Attribute Hierarchy (Level).
CALCULATE;
CREATE MEMBER CURRENTCUBE.[Measures].[Total On Hand Amount]
AS ([Measures].[On Hand Amount],Axis(1).Item(0).Item(0).Dimension.CurrentMember.Parent),
FORMAT_STRING = "#,#",
VISIBLE = 1 ;
I would like to make this MDX code work for any Dimension.Hierarchy regardless of number of Attribute Hierarchy (Level/s).
Any help is appreciated!!
You can use the ancestors function instead of parent. It takes a dimension parameter and a second parameter which shows how many levels you want to get (how deep in the tree to go). So if you know how many levels your dimension has you can use something like:
Ancestors(Axis(1).Item(0).Item(0).Dimension.CurrentMember, 5)
Instead of a number you can also add a dimension level as a second parameter. Then it will go as deep as the dimension level specified - so if you add the root dimension level it should get to there
(Axis(1).Item(0).Item(0).Dimension.Levels(0).Item(0), [Measures].[On Hand Amount])
Above gave me the correct answer, total for a measure for dynamic selection of any dimension but this MDX calculation would not work from PowerBI(DAX) report, which is merely PowerBI's limitation.
I got the TOTAL working now with this -
SCOPE(DESCENDANTS([Warehouses].[Warehouses],,AFTER));
[Measures].[Total On Hand Amount] = (ROOT([Warehouses]),[Measures].[On Hand Amount]);
END SCOPE;
I just have to repeat this SCOPE for each [Dimension].[Hierarchy] in the cube to make the TOTAL work for any selection including multiple dimensions from Power BI. It does not have dynamic functionality like Axis() did, but it yields the result I needed.
Hope this would help someone else too!!

MDX Calculated Member SubCube

I am relatively new to this depth of MDX, but here is my dilemma. My goal is to implement a calculated member using a .Net Stored Procedure. The calculation (XIRR) will be based on a set of cash flow dates and cash flow amounts. Ideally this would be a calculation in my cube that is available as a measure to Excel/Browser users.
So to start simple I am just trying to implement my own COUNT calculated member/measure (not even using .Net) to say count the # of members in a given dimensions based on the current context. So lets say I have a dimensions Customer with a Customer Id Key. And let's say there are a total of 100 customers in my database. So Count(Customer.CustomerId.AllMembers) would be 100. Now when you start using the browser and say filter on Customer.CustomerId.&1, Customer.CustomerId.&2 (customer id 1 and 2) I would expect my count calculated member to return 2 but it returns the total 100 count. I have tried using exists. I am sure there is something that I am just fundamentally not understanding yet.
Hopefully this makes sense, would hugely appreciate any help from someone that has a good understanding of SSAS/MDX and calculations. Thanks in advance.
Marty
You may have some issues here, I did when I tried to do a similar thing.
Your calculated member is not honouring the client sub-select, which is normal. What in theory you would do is create a dynamic set, and then use that in the calculated member to force the dimension count to be evaluated in the context of the subcube your filters have created. Mosha has a good article here: http://sqlblog.com/blogs/mosha/archive/2007/08/25/mdx-in-katmai-dynamic-named-sets.aspx
So you'd end up with something like:
CREATE DYNAMIC SET CurrentCube.Customers AS
EXISTING(Customer.CustomerId.CHILDREN);
CREATE MEMBER CurrentCube.Measures.CustomerCount AS
Customers.COUNT
Now the real problem you'll have is a bug in SSAS https://connect.microsoft.com/SQLServer/feedback/details/484865/calcuated-member-with-a-reference-to-dynamic-named-set-kills-the-cubes-performance so the code above, which will probably work just fine locally, will kill a production cube. This was an exciting learning experience for me.
See if you can get any of the workarounds to work, I couldn't.
I was able to get what I wanted, but I had to create query-scoped dynamic sets as part of the MDX query, I wasn't able to create it as a cube object:
WITH DYNAMIC SET Customers AS
EXISTING(Customer.CustomerId.CHILDREN);
MEMBER Measures.CustomerCount AS
Customers.COUNT
SELECT
Measures.CustomerCount
ON COLUMNS
FROM [Cube]
WHERE Customer.CustomerId.&[1]
Let us know how you get on.