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

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.

Related

How does SSAS populate the LEVEL_TYPE information in MDSCHEMA_LEVELS rowset

I ran the following DMV query on SSAS.
SELECT
[HIERARCHY_UNIQUE_NAME],
[LEVEL_NAME],
[LEVEL_NUMBER],
[LEVEL_CARDINALITY],
[LEVEL_TYPE]
from $system.mdschema_levels
where [DIMENSION_UNIQUE_NAME] = '[DATE]'
AND [CUBE_NAME] = 'Adventure Works'
AND [LEVEL_NAME] <> '(All)'.
I get a lot of unexpected LEVEL_TYPES
I wanted to understand what do the LEVEL_TYPE like 4289, 4578, 4385, 4759 signify? Are they computed algorithmically or is they a documentation resource one can refer to?
These Level_TYPE are determined the "Type" property of the dimension attribute that you set in dimension design window of your SSAS project. In case if you set the Type to regular you get 0 else , if you select from one of the types present you get its identifier. The interesting bit is if the HIERARCHY_UNIQUE_NAME has a attribute hierarchy, it returns the identifier for the attribute hierarchy, if HIERARCHY_UNIQUE_NAME has user hierarchy, then the identifier is returned for the LEVEL_NAME's base attribute. For example in the result below, take a look at the two rows that return 68 in LEVEL_TYPE, the first row is being reported as attribute hierarchy, the second as user hierarchy's level(Notice the Level_Number 3 and the difference between the HIERARCHY_UNIQUE_NAME and LEVEL_NAME)
Edit: Specific type details
4289: type Date,
4578: type QuaterOfYear,
4385: type HalfYearOfYear,
4759: type WeekOfYear

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 - Is it possible to have two unrelated dimension members in one row?

I need to create the table of the following structure in MDX (to be used in SSRS report):
For that I have 2 dimensions and one measure:
Option dimension, with option type and option value attributes
Standard dimension, with IsStandard flag
Price measure
In first column I need to show all option type attributes,
in second all value attributes where IsStandard flag is set to [Y],
in third values chosen by user in parameters and
in fourth prices for components selected by user.
Is it possible to do the above in single MDX? Or will I be better off creating 2 distinct queries and creating 2 tables for them?
EDIT: Since my updates won't fit into the comment, I will add some thoughts here.
EXISTS function from answer below does not filter the result set, I don't get standard values but all possible values concatenated. When I issue the following code:
SELECT
[Measures].[Price] ON 0,
NON EMPTY [Option].[Option Type].children
*
[Option].[Option Value].children ON 1
FROM [Cube]
WHERE
(
[Standard].[IsStandard].&[Y],
[Configurations].[Configuration].&[conf1]
)
It returns the default values correctly, but if I use
SELECT
[Measures].[Price] ON 0,
[Option].[Option Type].children
*
EXISTS(
[Option].[Option Value].[Option Value].members
,([Standard].[IsStandard].&[Y],[Configurations].[Configuration].&[conf1])
) ON 1
FROM [Cube]
It does not filter the results.
If you can accept a slightly different order of columns, then this can be done in MDX, using a calculated measure which is actually a string (as you want to see a list of attributes values in column). This avoids having the same attribute twice in the rows:
WITH Member Measures.[Standard Value] AS
Generate(NonEmpty([Option].[Option Type].[Option Type].Members,
{([Standard].[IsStandard].&[Y],
Measure‌​s.[Price]
)}
),
[Option].[Option value].CurrentMember.Name,
", "
)
SELECT { Measures.[Standard Value], Measures.[Price] }
ON COLUMNS,
NON EMPTY
[Option].[Option Type].[Option Type].Members
*
{ #chosenValues } // the parameters value should be a comma separated list like "[Option].[Option value].[AMD], [Option].[Option value].[INTEL]"
ON ROWS
FROM [Your Cube]
WHERE [Configurations].[Configuration].&[conf1]
You can adapt the list separator (the last argument of the Generate function) to anything you like.
And in case there is more than one measure group that is related to the dimensions [Option], [Standard], and [Configurations], you should add the name of the measure group to use for determining the relationship as additional last parameter to the Exists, so that you and not the engine determines that. Just use the name of the measure group in either single or double quotes.
Yes it is, dimension will just be ignored. This is assuming you've all in the same schema / cube.
Note, depending on the OLAP Server you're using it's possible you've to change a flag that sends an error if you're using a dimensions that is not defined at Measure Group level.

MDX calculated dimension attribute

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)

MDX: using distinct count in YTD for calculated member

I have created new measure that counts distinct policies (this measure is called FK Policy Distinct Count).
Then I created new calculated member called CountPolicyEndorsesNull which counts all policies from FK Policy Distinct Count using a filter:
(([Policy].[Endorses].&[0],[FK Policy Distinct Count]).
Than I did new calculated member called CountPolicy:
SUM(EXCEPT([Policy].[Policy Status].[Policy Status],[Policy].[Policy Status].&[Void]), [Measures].[CountPolicyEndorsesNull])
Next, I created a new member CountNewBound
SUM(
{
[Submission].[Tran Type].&[New], [Submission].[Tran Type].&[Developed]
},
[Measures].[CountPolicy]
)
And finally, YTDCountNewBound
SUM(YTD([Invoice Date].[Date Hierarchy].CurrentMember), [Measures].[CountNewBound])
Obviously, SUM function doesn't work in this case. Any idea how to make proper YTD count for calculated member?
Distinct count is a special measure which should be managed with a little more care. The rational behind this is that the when evaluating the measure a set of previous values is kept in memory. In order to improve performance, this structure is not passed and it's quickly converted to a scalar value.
Going back to your problem :
Distinct count can be evaluated over a tuple without problem, but you'll get in problems once you try to evaluate over a set of tuples. A possible, but costly and not always possible, is to create a hierarchy of values so you can convert your set in a member of a dimension.
In your case instead of using YTD([Invoice Date].[Date Hierarchy].CurrentMember) function using another hierarchy -> [Invoice Date].[YTD Date Hierarchy].
All this depends on the specific OLAP implementation you're using, but I guess holds true for mainly all OLAP vendors.