Often attributes have their own attribute hierarchy by default. Not a user hierarchy. Just to make sure I'm clear on my terminology:
Attribute hierarchy:
[Dim City].[State Name]
Attribute:
[Dim City].[State Name].[State Name]
Attribute member:
[Dim City].[State Name].[State Name].&[Kansas]
From the standpoint of writing MDX queries, most of the time using either in a cross join gives desired results. Occasionally when I'm doing more complex queries, I hit situations where using the [Dim State].[State Name] in a cross join will give me combinations of values which aren't related.
[Dim City].[State Name]
* [Dim City.[City Name]
Usually using one or the other produces identical results, sometimes not. In more complex queries sometimes I get combinations of unrelated members like (Atlanta, Kansas), and then I change it to below and it works correctly:
[Dim City].[State Name].[State Name]
* [Dim City.[City Name].[City Name]
My main questions is to not figure out why those specific queries may not work correctly, but really what the difference is between using on or the other.
It seems like both produce a set of the same members.
Both seem to have individual members directly within them:
[Dim City].[State Name].[State Name].&[Kansas]
[Dim City].[State Name].&[Kansas]
I understand user hierarchies, but have never really figured out what the functional difference is with these default attribute hierarchies.
Usually, each attribute hierarchy exists of two levels: A top level that contains the 'All' member and the bottom level that contains the attribute elements.
The overall structure of the parts of a dimension in an MDX expression are like the following:
[Dimension name].[Hierarchy name].[Hierarchy level name].[Member Name]
[Dimension name].[Hierarchy name].[Hierarchy level name].&[Member Key]
Your first example
[Dim City].[State Name]
* [Dim City.[City Name]
is a shortcut for
[Dim City].[State Name].Members
* [Dim City.[City Name].Members
So, [Dim City].[State Name].Members would be resolved to {[Dim City].[State Name].[All], [Dim City].[State Name].[Alabama], [Dim City].[State Name].[Alaska], [Dim City].[State Name].[Arizona], ...} because you call the Members function on the hierarchy and not the level.
In your second example you include the level name and thus you'll get only the list of state names without the 'All' member.
If you'll get an invalid combination of state and city names in some queries you should check your attribute relationships. The city name attribute should point to the state name attribute, but you should do this only, if your key values of your attributes follow this relationship. E.g. if you have cities with the same name in several states, every city needs its own key.
BTW: You should use & instead of $ in your MDX queries, but I assume that to be a typo.
Related
There's an issue facing me. I am working on SSAS 2017 and I have dimensions used by 3 cubes. In one of my cube When I drag and drop my dimension member instead of getting the literal name of dimension member ([xxxx].[yyyy].[aaaa]) I got number [xxxx].[yyyy].&[1] ..
Please someone can tell me how to avoid this kind of behavior ?
To be more precise when i drag and drop in my mdx statement :
I have :
[Dim Sales Territory].[Sales Territory].[1] , [Dim Sales Territory].[Sales Territory].[2]
I want to get :
[Dim Sales Territory].[Sales Territory].[Canada] , [Dim Sales Territory].[Sales Territory].[Australia]
The [Dim Sales Territory] has key column [Sales Territory Id]
Thank you
If you change the MemberNamesUnique property to true on the Sales Territory attribute in the Dim Sales Territory dimension editor and redeploy you’re cube then the drag and drop member unique name reference should change.
But my question is why you want to do this? Do you just want the code to be more readable? Are the names unique?
By the way, you will want to edit your question to put an & on member unique names which reference by key ([Dim Sales Territory].[Sales Territory].&[1]). If you omit these & then you reference the name property of an attribute. If truly you aren’t getting an & then the problem is that you have used the wrong column as the name column and have already set MemberNamesUnique=true.
I am trying to create a query but it utilizes two different dimensions. I receive this error "Members, tuples, or sets must use the same hierarchies in the function." I've run this with/without the brackets in the row section and got the same error. How do I resolve this issue?
Error Message/MDX Query
You are using two different hierarchies of the same dimension [Dim Course] in the tuple which is not allowed.
You will have to change your query, something like this should work:
select {[Measures].[Dim Course Count],[Measures].[Dim Semester Count]} on 0,
{([Dim Course].[Course Code].[Course Code], [Dim Semester].[Academic Year].[Academic Year]) } on 1
from [CCSE-DM]
where [Dim Course].[Level1].[Level1]
Short question:
Any idea how I can pull the name from one dimension entry and apply it to another as filter?
Long description: My cube has has dimensions for manufacturer and seller, and I only need sales for "themselves". The dimensions are loaded from distinct tables in the source but have entries with the exact same name.
Manufacturer Seller
A A *
A D
B B *
C C *
C A
C D
A, B and C sell their products themselves, A and C also sell through reseller D. C also sells through A. I'd like to filter for the marked rows only (names matching).
In SQL this would be simple, or the cube might be easily enhanced to flag "own sales", but both options are not available. I need to query the cube "as is".
I tried using STRTOMEMBER and CURRENTMEMBER like so (with NAME and MEMBER_NAME):
STRTOMEMBER("[Dim Seller].[Seller].[" + [Dim Producer].[Producer].CURRENTMEMBER.NAME + "]
That actually works, syntactically, but CURRENTMEMBER seems to always evaluate to ALL and delivers the (correct) measure value for the ALL element yet not the one for matching name.
I also tried to create a WHERE setting the two names equal
[Dim Seller].[Seller].CURRENTMEMBER.NAME = [Dim Producer].[Producer].CURRENTMEMBER.NAME
but that is very SQL and not valid in MDX.
The whole query looks like this:
SELECT
NON EMPTY {
[Measures].[Value]
} ON COLUMNS
, NON EMPTY { (
{
[Dim Producer].[Producer].[A]
, [Dim Producer].[Producer].[B]
, [Dim Producer].[Producer].[C]
}
* [Dim Seller].[Seller].[Seller].ALLMEMBERS
// This line needs to be trimmed to same name as producer
) } ON ROWS
FROM
[Cube]
The producer list is coming from a config file and string-concatenated to the query and subject to change. Having a second seller list to be kept in sync would be a burden but also (when C sells through A) deliver wrong results.
Any idea how I can pull the name from one dimension entry and apply it to another?
The HAVING clause might help you:
SELECT
NON EMPTY {
[Measures].[Value]
} ON COLUMNS
, NON EMPTY {
{
[Dim Producer].[Producer].[A]
, [Dim Producer].[Producer].[B]
, [Dim Producer].[Producer].[C]
}
* [Dim Seller].[Seller].[Seller].ALLMEMBERS
}
HAVING
[Dim Seller].[Seller].CURRENTMEMBER.MEMBER_NAME =
[Dim Producer].[Producer].CURRENTMEMBER.MEMBER_NAME
ON ROWS
FROM
[Cube]
Use the GENERATE function to do the job for you.
with set Producers as
{[Dim Producer].[Producer].[A]
,[Dim Producer].[Producer].[B]
,[Dim Producer].[Producer].[C]}
set Sellers as
[Dim Seller].[Seller].members
//For every producer, get the seller who shares the same name.
set ProducersHavingSameNameAsSellers as
GENERATE(Producers, GENERATE(Sellers, filter
(Sellers,
[Dim Seller].[Seller].CURRENTMEMBER.MEMBER_NAME =
[Dim Producer].[Producer].CURRENTMEMBER.MEMBER_NAME
)
)
)
SELECT
NON EMPTY [Measures].[Value] ON COLUMNS,
ProducersHavingSameNameAsSellers ON ROWS
FROM [Cube]
I have an ordinary DimProduct which has a snowflaked DimPriceList where I store for each ProductKey different prices for the products.
In a MDX, depending on certain product properties, I would like to display different prices for the products. The MDX would look something like this.
CASE
WHEN [Dim Product].[Value Group].CurrentMember.MEMBERVALUE = '02' THEN
CASE
WHEN [Dim Product].[Stock Account Nr].CurrentMember.MEMBERVALUE = 101 THEN
([Dim Price List].[Sales1])
WHEN [Dim Product].[Stock Account Nr].CurrentMember.MEMBERVALUE = 102 OR
[Dim Product].[Stock Account Nr].CurrentMember.MEMBERVALUE = 103 THEN
([Dim Price List].[Valuation])
ELSE
0
END
ELSE
1
END
How can I now access the current membervalue of the DimPriceList? I just get 'All' as result and not the actual value for the current member. I've also tried [Dim Price List].[Valuation].CurrentMember.MEMBERVALUE but with no success. Appreciate any sort of help or hints.
You get the [All] member because it IS the default value. In absence of any scope, the engine bases it's calculation around the default member. If you want the output to change based on the current member of Product, you should attempt at creating a calculated member. Encapsulate the logic above into the script which chooses the requisite measure depending upon the current member. I am assuming you must be having Sales1 and Valuation in form of Measure in your cube. If that is the case your calculated member should choose the requisite measure based on the MEMBERVALUE or you can employ
....
[Dim Product].[Stock Account Nr].CurrentMember IS [Dim Product].[Stock Account Nr].&[101]
....clause.
That said, you need to give some scope.
I have a simple olap cube - one set of measures and some unexciting dimensions.
I've add one calculation to get the "percent of total" sales against the gross sales measure. The code for this calculation is:
([Dim Stores].[Store Name].CurrentMember, [Measures].[Gross Sales])
/
([Dim Stores].[Store Name].Parent, [Measures].[Gross Sales])
This works.
Within the store dimension, there is a hierarchy called 'By State' where the stores are contained within.
Two questions please:
1. Any idea why the calculation would not work when I use the the 'By state' hierarchy i.e. the same calculation grouped by the next level up?
The state problem aside, any idea why my grand total shows an error even when I just use the Store Name?
TIA!
In poking around, I found a template within the "calculation tools" called "Percentage of Total". Using it, I translated my calculation to this:
Case
// Test to avoid division by zero.
When IsEmpty
(
[Measures].[Gross Sales]
)
Then Null
Else ( [Dim Stores].[By State].CurrentMember, [Measures].[Gross Sales] )
/
(
// The Root function returns the (All) value for the target dimension.
Root
(
[Dim Stores]
),
[Measures].[Gross Sales]
)
End
It worked!