MDX calculated dimension attribute - ssas

Is it possible to create a query scoped dimension attribute (as is done with measures) using the WITH statement.
I'm trying to do something like this:
WITH
MEMBER [Customer].[Has Child At Home] AS
IIF( [Customer].[Number of Cars Owned] > 0,
True,
False
)
And then use the above attribute in a select statement however it is giving me an error saying that the customer dimension has more than one hierarchy and that one needs to be specified.

In this format it requires a hierarchy, to build on your code example [Number of Cars Owned] would need to be a hierarchy:
WITH
MEMBER [Customer].[Number of Cars Owned].[Has Child At Home] AS
IIF([Customer].[Number of Cars Owned] > 0, "True", "False")
SELECT
{[Customer].[Has Child at Home]} ON COLUMNS,
[DimExample].[AttributeExample].Members ON ROWS,
FROM [CubeExample]
See Creating Query-Scoped Calculated Members (MDX)

Related

MDX calculated member dimension context

I have the following calculated member which represents the quantity of "overstocked" products:
WITH
MEMBER [Measures].[Overstocked Items Count] AS
FILTER(
[Items].[Item No].CHILDREN,
[Measures].[Overstocked Qty] > 0
).COUNT
It works just fine for any linked to the measure group dimension except for the Items dimension itself and the reasons are obvious. Is there a way to create a calculated member that would respect the context it is evaluated in? So basically if this member is evaluated against an item group code I need items count by those groups, not the entire items set.
EXISTING is a useful keyword that can add the current context to your measure:
WITH
MEMBER [Measures].[Overstocked Items Count] AS
FILTER(
EXISTING([Items].[Item No].CHILDREN),
[Measures].[Overstocked Qty] > 0
).COUNT
EXISTING is very good when you want to know the members present from a different hierarchy within the same dimension. e.g. say you have U.S.A selected from the country hierarchy (in geography dimension) and you need to count state/county members from a stateCounty hierarchy that is also part of the geography dimension then EXISTING is the correct choice.
If you want to go across dimensions so say you have U.S.A selected and you'd like to count customer, from the customer dimension who are associated with the U.S.A then I don't think EXISTING will work - you'll need to explore either EXISTS or NONEMPTY.

MDX to show Measure property

I'm familiar with how to get member properties into an MDX result-set: create a calculated member using WITH.
The problem is when the member whose properties I want is a measure, not a dimension member. Because the calculated member is created on the Measures hierarchy, I get the dreaded "The Measures hierarchy already appears in the Axis0 axis" error. Here's the query I'm running:
WITH MEMBER Measures.MeasureType AS
Measures.CurrentMember.Properties('MEMBER_TYPE')
SELECT
MeasureType ON 0,
Measures.Members on 1
FROM TheCube
What I'm after is simply a list of all the measures ON 1 (this works, in itself); but with the measure's MEMBER_TYPE showing as the one column ON 0
You can't have members from the same hierarchy on both axes. There are two ways to get rid of this error.
1. Create the calculated member on some other dimension
WITH MEMBER [SomeDimension].[SomeHierarchy].MeasureType AS
Measures.CurrentMember.Properties('MEMBER_TYPE')
SELECT
[SomeDimension].[SomeHierarchy].MeasureType ON 0,
Measures.Members on 1
FROM [TheCube]
2. Have them in a set and not on different axes.
WITH MEMBER Measures.MeasureType AS
Measures.CurrentMember.Properties('MEMBER_TYPE')
SELECT
{Measures.MeasureType, Measures.Members} ON 0
FROM [TheCube]
Discarding the second method as it gives a static value. What's really needed is a cross-tab value. So sticking with first method.

using scope with calculated member

I have problem in my calculated member. Whenever this member involve in calculation or query it take large time to execute. I am trying to narrow down execution time.
I have to remove IIF condition from the members and start using scope instead.
CREATE Member CurrentCube.[Measures].[AvgAmount] as
IIF(ISLeaf([Customer].[ParentCustomer].currentmember),
[Measures].[Value],
(SUM([CCube^Customer].[ParentCustomer].CURRENTMEMBER.CHILDREN) /
COUNT([Customer].[ParentCustomer].CURRENTMEMBER.CHILDREN))
) ,
Format_String = "#.0000000;-#.0000000;0;0",
Non_Empty_Behavior = [Measures].[Amout];
I have created hierarchy of customer which is [ParentCustomer] here. I want to see avg amount of all the children under the parent customer but when I am looking child level which does not have any children in it should only show the [Measures].[Amout].
Thanks in advance
Regards,
Sam
From your question, I assume you really want to have the average of the children, and not the average of all leaf level descendants. The latter could be implemented as follows:
Create a new measure group on the customer dimension table which has a single measure 'customer count' which would just be implemented as count - or of your customer dimension as a granularity that is finer than a single customer - countdistinct of the customer key or something like this.
Then just define your measure as
CREATE Member CurrentCube.[Measures].[AvgAmount] as
[Measures].[Value] / [Measures].[customer count],
Format_String = "#.0000000;-#.0000000;0;0",
Non_Empty_Behavior = [Measures].[Amout];
This assumes that the aggregation of [Measures].[Value] is defined as sum or one of the semi additive aggregations, but not max or min or something similar.
However, I assume from your question that this is not what you want. Instead you want to see the average of the children at each level. And I assume that [Customer].[ParentCustomer] is a standard user hierarchy and not a parent child hierarchy. Then, the approach suggested in the title, using SCOPE, would work. Let's assume you have three levels in your [Customer].[ParentCustomer] hierarchy:
The (implicitly defined) All level, just containing the All member
level A, built from attribute A of the dimension
level B, which is the leaf level and built from attribute B of the dimension
Then, under similar assumptions about the [Measures].[Value] aggregation, you could define the AvgAmount measure as follows:
// create the measure as it is correct for level B:
CREATE Member CurrentCube.[Measures].[AvgAmount] as
[Measures].[Value],
Format_String = "#.0000000;-#.0000000;0;0",
Non_Empty_Behavior = [Measures].[Amout];
// overwrite the definition for level A:
SCOPE([Customer].[ParentCustomer].[A].Members);
[Measures].[AvgAmount] = [Measures].[Value] / (EXISTING [Customer].[B].[B].Members).Count
END SCOPE;
// overwrite the definition for the ALl level:
SCOPE([Customer].[ParentCustomer].&[All]);
[Measures].[AvgAmount] = [Measures].[Value] / (EXISTING [Customer].[A].[A].Members).Count
END SCOPE;
This approach, using SCOPE, would not work for a parent child hierarchy, buta syou do not write you have one, I just assume you don`t.

How to create a member that filters data across dimensions?

I would like to create a calculated member, (or whatever is best) that will filter data based on a set of conditions.
Example: If [dimension1].[attribute1] = 'Y', and if [dimension2].[attribute2] between 0 and 8, then "call this member "Red", else, call this member "black".
I would like to then be able to drag whichever member i need to the where clause of a MDX statement, and have it filter the data based on the conditions i specified.
I am new to this, and if someone can give me a sample query to do this, i would sure appreciate it!
WITH
MEMBER A AS
STRTOVAL( [dimension2].[attribute2].currentmember.name)
MEMBER B AS
IIF(A >=0 AND A < 9 AND [dimension1].[attribute1].currentmember IS [dimension1].[attribute1].&[y],'Red', 'Black'
I created two members. The first handles the range. Attributes are stored as text, they need to be converted. This was it's own member due to needing to reference it twice in member B. Member B is a basic IIF that includes the conditions and outputs specified.
For these members to work, Dimension1.attribute1 and dimension2.Attribute2 will need to be present in your select statement.

How can I use an MDX Level property in the slicer?

Suppose I have a [Sales] cube which has a [Store] level and a store has a "type" property.
Which query should I use for showing the sum of sales for all the stores of type "Supermarket"?
(e.g. You sold 6M $ in all stores of type "Supermarket")
If you want to access member properties, you can use .properties("propertyname")
You would have to create a custom set which first filtered and then aggregated all the members of the [Store] level which matched the property value "Supermarket".
My MDX skills are a bit rusty...
WITH MEMBER [Stores].[SupermarketSweep] AS 'Aggregate([Filter([Stores].[Store].members, [Stores].currentMember.properties("type") = "Supermarket"))'
SELECT {[Stores].[SupermarketSweep]} ON ROWS,
{[Measures].[Whatever]} ON COLUMNS
FROM [Sales]
If you wanted to use the "type" property in queries you would be better to make it a browseable attribute.