MDX with snowflaked dimensions - ssas

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.

Related

MDX Scope to get denominator

I have a SSAS multidimensional cube and i am trying to calculate a denominator for a query by using a scope statement.
I am trying to assign the measure "Total SalesCumulative" the total value of all the sales for all the stores. I want this to stay being the total value and not get sliced when in a pivot table. The measure called Total Sales sums up all the sales for each store. I have gotten as far as the below but this just returns the value for each store and shows the same value as Total Sales.
SCOPE ([Measures].[Total SalesCumulative],[Dim Store].[Store Name].members);
THIS = ([Dim Store].[Store Name].[All],[Measures].[Total Sales]);
END SCOPE;
Has anyone got any suggestions how I can amend this?
I have checked your formula on Adventure Works database, and it seems correct. Just to be sure, you can check what you get with the query like the one below in SSMS (without making scope assignment):
with member measures.[All Order Count] as
([Measures].[Internet Order Count],[Product].[Model Name].[All Products] )
select {[Measures].[Internet Order Count] ,measures.[All Order Count] } on 0,
[Product].[Model Name].members on 1
from [Adventure Works]
Have you tried to clear cash before running the query after you made the change?
Secondly, maybe there is some other scope assignment in the script, that affects the same measure and dimension and overrides your formula, because the last scope assignment wins.
Try to add FREEZE(THIS) to your scope statement just to check if it will change the numbers:
SCOPE ([Measures].[Internet Order Count],[Product].[Model Name].members);
THIS = ([Product].[Model Name].[All Products] , [Measures].[Internet Order Count]) ;
FREEZE(THIS);
END SCOPE;

The MDX function CURRENTMEMBER failed because the coordinate for the 'Date' attribute contains a set

I'm trying to run this query:
select [Dim Date].[Date] on ROWS,
{[Measures].[Available Time Net],[Measures].[Logged On Time Net]} on columns
from [OTS Agent Time Net Data]
where {[Dim Date].[Date].&[08/01/2014]:[Dim Date].[Date].&[12/31/2014]}
I want to get the measures that exist in the where clause, but I also want to show the dates on the rows. I keep getting an error.
Why not just add the set directly to the ROWS ?
SELECT
NON EMPTY
{
[Dim Date].[Date].&[08/01/2014] : [Dim Date].[Date].&[12/31/2014]
} ON ROWS
,{
[Measures].[Available Time Net]
,[Measures].[Logged On Time Net]
} ON COLUMNS
FROM [OTS Agent Time Net Data];
You cannot use the same hierarchy ([Dim Date].[Date]) both on one axis and in the slicer (MDX tutorial); I guess using a sub-query would be fine for your example:
select
[Dim Date].[Date] on ROWS,
{[Measures].[Available Time Net],[Measures].[Logged On Time Net]} on columns
from (
select {[Dim Date].[Date].&[08/01/2014]:[Dim Date].[Date].&[12/31/2014]} on 0
from [OTS Agent Time Net Data]
)
Hope that helps.
(edit: using a named-set or using the slicer content right in the axis - see other responses - is a bit different because the request is filtering on a range of days but select [Dim Date].[Date] does not necessarily displays days; that could for example be the 'All' of the hierarchy of [Dim Date].[Date])
I agree with Marc's answer and that's probably the best way to do it. But there is one more way to do it, which doesn't need subselect, by making use of named sets.
with set DateRange AS
{[Dim Date].[Date].&[08/01/2014]:[Dim Date].[Date].&[12/31/2014]}
select NON EMPTY DateRange on ROWS,
{[Measures].[Available Time Net],[Measures].[Logged On Time Net]} on COLUMNS
from [OTS Agent Time Net Data]
EDIT
As per your request, if you want to additionally filter by time, here's one way to proceed. Replace the defenition of set DateRange with the below:
with set DateRange AS
EXISTS({[Dim Date].[Date].&[08/01/2014]:[Dim Date].[Date].&[12/31/2014]}
,[Dim Time].[Time].&[1930]
, "Time Net"
)
Few things which you need to fill in here..
Assuming time dimension's hierarchy to be [Dim Time].[Time]. Please replace with the actual name along with the member's format(Assumed it to be &[1930]
Also, Time Net is the measure group name to which the measures [Measures].[Available Time Net] and [Measures].[Logged On Time Net] belong to. Again, replace with original name.

Calculated SSAS Member based on multiple dimension attributes

I'm attempting to create a new Calculated Measure that is based on 2 different attributes. I can query the data directly to see that the values are there, but when I create the Calculated Member, it always returns null.
Here is what I have so far:
CREATE MEMBER CURRENTCUBE.[Measures].[Absorption]
AS sum
(
Filter([Expense].MEMBERS, [Expense].[Amount Category] = "OS"
AND ([Expense].[Account Number] >= 51000
AND [Expense].[Account Number] < 52000))
,
[Measures].[Amount - Expense]
),
VISIBLE = 1 , ASSOCIATED_MEASURE_GROUP = 'Expense';
Ultimately, I need to repeat this same pattern many times. A particular accounting "type" (Absorption, Selling & Marketing, Adminstrative, R&D, etc.) is based on a combination of the Category and a range of Account Numbers.
I've tried several combinations of Sum, Aggregate, Filter, IIF, etc. with no luck, the value is always null.
However, if I don't use Filter and just create a Tuple with 2 values, it does give me the data I'd expect, like this:
CREATE MEMBER CURRENTCUBE.[Measures].[Absorption]
AS sum
(
{( [Expense].[Amount Category].&[OS], [Expense].[Account Number].&[51400] )}
,
[Measures].[Amount - Expense]
),
VISIBLE = 1 , ASSOCIATED_MEASURE_GROUP = 'Expense';
But, I need to specify multiple account numbers, not just one.
In general, you should only use the FILTER function when you need to filter your fact table based on the value of some measure (for instance, all Sales Orders where Sales Amount > 10.000). It is not intended to filter members based on dimension properties (although it could probably work, but the performance would likely suffer).
If you want to filter by members of one or more dimension attributes, use tuples and sets to express the filtering:
CREATE MEMBER CURRENTCUBE.[Measures].[Absorption]
AS
Sum(
{[Expense].[Account Number].&[51000]:[Expense].[Account Number].&[52000].lag(1)} *
[Expense].[Amount Category].&[OS],
[Measures].[Amount - Expense]
),
VISIBLE = 1 , ASSOCIATED_MEASURE_GROUP = 'Expense';
Here, I've used the range operator : to construct a set consisting of all [Account Number] members greater than or equal to 51000 and less than 52000. I then cross-join * this set with the relevant [Amount Category] attribute, to get the relevant set of members that I want to sum my measure over.
Note that this only works if you actually have a member with the account number 51000 and 52000 in your Expense dimension (see comments).
An entirely different approach, would be to perform this logic in your ETL process. For example you could have a table of account-number ranges that map to a particular accounting type (Absorption, Selling & Marketing, etc.). You could then add a new attribute to your Expense-dimension, holding the accounting type for each account, and populate it using dynamic SQL and the aforementioned mapping table.
I don't go near cube scripts but do you not need to create some context via the currentmember function and also return some values for correct evaluation against the inequality operators (e.g.>) via the use of say the membervalue function ?
CREATE MEMBER CURRENTCUBE.[Measures].[Absorption]
AS sum
(
[Expense].[Amount Category].&[OS]
*
Filter(
[Expense].[Account Number].MEMBERS,
[Expense].[Account Number].currentmember.membervalue >= 51000
AND
[Expense].[Account Number].currentmember.membervalue < 52000
)
,
[Measures].[Amount - Expense]
),
VISIBLE = 1 , ASSOCIATED_MEASURE_GROUP = 'Expense';
EDIT
Dan has used the range operator :. Please make sure your hierarchy is ordered correctly and that the members you use with this operator actually exist. If they do not exist then they will be evaluated as null:
Against the AdvWks cube:
SELECT
{} ON 0
,{
[Date].[Calendar].[Month].&[2008]&[4]
:
[Date].[Calendar].[Month].&[2009]&[2]
} ON 1
FROM [Adventure Works];
Returns the following:
If the left hand member does not exist in the cube then it is evaluated as null and therefore open ended on that side:
SELECT
{} ON 0
,{
[Date].[Calendar].[Month].&[2008]&[4]
:
[Date].[Calendar].[Month].&[1066]&[2] //<<year 1066 obviously not in our cube
} ON 1
FROM [Adventure Works];
Returns:

SSAS: Percent of Total not working in hierarchy

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!

SSAS & OLAP cube: twice same measure

I'm not very experienced in OLAP Cube + MDX, and I'm having a hard time trying to use twice the same measure in a cube.
Let's say that we have 3 Dimensions: D_DATE, D_USER, D_TYPE_OF_SALE_TARGET and 3 tables of Fact: F_SALE, F_MEETING, F_SALE_TARGET
F_SALE is linked to D_USER (who make the sale) and D_DATE (when)
F_SALE_TARGET is linked to D_USER, D_DATE, D_TYPE_OF_SALE_TARGET (meaning: user has to reach various goals/targets for a given month).
I can browse my cube:
Rows = Date * User
Cols = Number of sale, Total amount of sale + the value of 1 target (in the WHERE clause, I filter on [Dim TYPE SALE TARGET].[Code].&[code.numberOfSales])
How can I add other columns for other targets? As all the targets are in the same table, I don't see how to add a second measure from [Measures].[Value - F_SALE_TARGET] linked to a different code, ie. [Dim TYPE SALE TARGET].[Code].&[code.amountOfSale].
your question is not clear to me but it seems like one way to accomplish that is by creating Calculated Members. Basically, select you cube in BIDS, go to the Calculations tab and create Calculated Members. You would be able to insert your MDX query there. For each target type you can create a different calculation such as: ([Measures].[Value - F_SALE_TARGET], [Dim TYPE SALE TARGET].[Code].&[code.amountOfSale])