Dimensions dragged in filter pane do not slice scoped measures - ssas

A measure 'X' gets its value from different fact tables.Lets consider Time (Fiscal Week, Month)dimension and Channel dimension. For different combination of attributes in these two dimensions X will get its value from different tables as follows:
Week + Channel - gets from table FactTrafficByWeekChannel
Week - gets from table FactTrafficByWeek
Month + Channel - gets from table FactTrafficByMonthChannel
Month - gets from table FactTrafficByMonth
To achieve this I added these fact to cube and created a calculated measure and scope scripts to overwrite the scope. Following is the scope script statement:`
CALCULATE;
CREATE MEMBER CURRENTCUBE.[Measures].[Y]
AS (0),
FORMAT_STRING = "Standard",
VISIBLE = 1;
Scope
([Measures].[Y],[Dim Time].[Fiscal Week].[Fiscal Week].Members
) ;
This = [Measures].[X - Vw Fact Total Weekly Traffic];
End Scope ;
Scope
([Measures].[Y],[Dim Time].[Fiscal Week].[Fiscal Week].Members,
[Dim Campaign].[Channel].[Channel].Members
) ;
This = [Measures].[X - Vw Fact Total Weekly Traffic By Channel];
End Scope ;
Scope
([Measures].[Y],[Dim Time].[Fiscal Month].[Fiscal Month].Members
) ;
This = [Measures].[X - Vw Fact Monthly Traffic];
End Scope ;
Scope
([Measures].[Y],[Dim Time].[Fiscal Month].[Fiscal Month].Members,
[Dim Channel].[Channel].[Channel].Members
) ;
This = [Measures].[X - Vw Fact Monthly Traffic By Channel];
End Scope ;
`
Above code works fine when corresponding dimension attributes are dragged in browsing pane but do not work when added to filter pane.
Fiscal Week dimension dragged to browsing pane this works. But
Fiscal Week dimension dragged to filter pane does not work.
This is because attributes added to filter pane are added as sub-cube statements.
Is there a way to achieve this when attributes are dragged to filter pane as well?
Time dimension Attribute relationship (as asked by Greg)
Any help is highly appreciated. Thanks in advance

One way is using dynamic named set as described in this post in the "Using dynamic sets to detect subselects" section.
Add this to the bottom of your existing MDX script:
Create dynamic named set CurrentCube.[SelectedWeeks] as [Dim Time].[Fiscal Week].[Fiscal Week].Members;
Scope
([Measures].[Y],[Dim Time].[Fiscal Month].[All],
[Dim Time].[Fiscal Week].[All],
[Dim Channel].[Channel].[All]
) ;
This = iif(SelectedWeeks.Count<[Dim Time].[Fiscal Week].[Fiscal Week].Members.Count,[Measures].[X - Vw Fact Total Weekly Traffic],0);
End Scope ;
But the problem with that approach is that it is going to get totally out of control checking all the permutations of single select on channel vs multi select on week, etc. And it will likely be slow.
Instead I would recommend removing the Create Member statement for Y from your MDX script and adding a new measure to your "by channel by week" measure group. Call the new physical measure Y and make it a Sum and connect it to a new SQL column that returns 0 on every row. This is just a placeholder measure you will do scoped assignments against. Why physical? When you make a scoped assignment on a physical measure at the channel level for example that assignment aggregates up. (Assignments to calc measures don't aggregate up.) This helps solve the multiselect issue. You assign at the channel level for example and then the All channel number is correct even under multiselect.
That being said, I am not optimistic you will be able to figure out the correct order of scoped assignments so that all 4 of your measures show up where you want with proper multiselect handling. But feel free to try.
One tip is to use Freeze([Measures].[Y], [Dim Time].[Fiscal Month].[All]) after one scoped assignment to months if you are happy with that portion of the cube but find subsequent scoped assignments are changing parts you were happy with.
If you need further help include a screenshot of the Attribute Relationships tab for Dim Time.

Related

Total Sum of Calculated member is wrong

I have there tables:
Artikal (eng. Item)
Grupa (eng. Group)
Potrosnja (eng. Consumption)
Potrosnja is my Measure table and Artikal is Dimension. Grupa contains also a parent-child relationship between groups. For now, is only one level. Inside the Artikal dimension I created
Hierarchy: Grupa.ParentId, Grupa.GrupaId, Artikal.Id. Name of Hierarhcy is PGA.
This shows well in Power BI. I also create some calculated Members: Cijena LY and Vrijednost LY.
I need to create a calculated member and the formula goes
(Cijena - Cijena LY)* Kolicina
First I tried to create like a calculated member but I saw that my total was also creating like the formula of totals of formulas. I want that my total for this member is SUM of calculated member column
I trying to do this with SCOPE, but I don't get the right result. Here is my script:
CREATE MEMBER CURRENTCUBE.[Measures].[Suma razlike] AS null,
VISIBLE = 1;
SCOPE([Measures].[Suma razlike],[Artikal].[PGA].members);
This =sum(
Descendants([Artikal].[PGA].CurrentMember,,LEAVES),
(([Measures].[Cijena]-[Measures].[Cijena LY])*[Measures].[Kolicina]));
END SCOPE;
Can somebody tell me what I am doing wrong? I creating this in Analysis services by Microsoft.
The solution was provided on the different blog by Alexei Stoyanovsky:
The problem was that was created hidden subselect. I needed to create a Dynamic set of Artikal. Here is solution:
CREATE DYNAMIC SET CURRENTCUBE.[MyTestSet] AS [Artikal].[Id].[Id].members;
SCOPE([Measures].[Suma razlike], [Artikal].[Id].members); --Includes All +
other members
This = case when [Artikal].[Id].currentmember.level.ordinal>0 then
([Measures].[Cijena]-[Measures].[Cijena LY])*[Measures].[Kolicina]
else
sum(existing [MyTestSet], ([Measures].[Cijena]-[Measures].[Cijena LY])*
[Measures].[Kolicina]) --All member is not included
end;
FORMAT_STRING([Measures].[Vrijednost - CPI])='Percent';
FORMAT_STRING([Measures].[Postotak razlike])='Percent';
FORMAT_STRING([Measures].[Razlika artikal - CPI])='Percent';
END SCOPE;

porting multidimensional SSAS to ICCube. Scope() equivalent? other gaps/issues?

Has anybody ever ported a complex ssas multidmensional cube to iccube? and have any advice to offer on lessons learnt/gaps between the two tools etc?
The major one i can see is scope(). What's the equivalent in iccube? nested if/case statements?
I have a list here. Anything else?
function | SSAS | iccube
------------------------|------------------------|------------------------
multi threaded calcs | no | yes
------------------------|------------------------|------------------------
fix/scope block code | SCOPE() | ??
------------------------|------------------------|------------------------
custom functions | clr.net but it's slow | mdx+
------------------------|------------------------|------------------------
generic date utility | third-party code that | ??
dimensions (eg generic | uses scope() eg |
prior period/prior | datetool |
corresponding period) | |
------------------------|------------------------|------------------------
We have a very mdx script calculation heavy cube, and the single threaded nature of the SSAS calculation engine is a real bottleneck. None of the other olap tools we've looked at have been fast enough or had a rich enough language
We use disconnected utility dimensions to drive the functionality, and need to have a date utility dimension (we use a version of this http://sqlmag.com/sql-server-analysis-services/optimizing-time-based-calculations-ssas), use AXIS() extensively, and have recursive sum product across descendents of a hierarchy for a non-additive measure.
Our cube isn't a self service reporting cube. It's a multidimensional calculation engine for our app with a fixed generic schema
Update 1: A simpler example of how we use scope. ic, You mention 'robust' workarounds exist. What would they be for code like this?
// Assumes the date utility dim has been setup as with the priorperiod function as [Dim Date Calculations].[Date Calculations].[Prior Period]
// DimBenchmark is a single attribute disconnected utility dimension. The initial/default value is DimBenchmark.Benchmark.None ie do nothing. The remainder are dynamically set based on code. hardcoded below for simplicity
Scope(DimBenchmark.BenchMark.PriorPeriod);
THIS = [Dim Date Calculations].[Date Calculations].[Prior Period]; // assign the value of some physical and utility dim members to new benchmark attributes. Allows us to only refer to dimbenchmark in subsequent code, irrespective of number of benchmarks or the src dimension.attribute
END SCOPE;
SCOPE(DimBenchmark.BenchMark.Budget);
THIS = DimScenario.Scenario.Budget; //we also have a budget
END SCOPE;
.... // any number of other benchmarks
Create measure currentcube.measures.ComplexCalc as NULL;
SCOPE (measures.ComplexCalc); // this code will only change how complex calc behaves
SCOPE (DimBenchmark.Benchmark.All - DimBenchmark.Benchmark.None); // this will only change the ComplexCalc when the active benchmark selection is not "none"
this= (some measure,Complex subcube etc);
End Scope;
End Scope;
the benefit of this is that complexcalc is null by default. it only gets a value when it meets specific conditions. the main reason to use scope is for speed. Much faster than if/case blocks (and simpler understand)
i dont need to explicitly define which benchmarks are valid, just which benchmark isn't.
and below is how we've implemented the date utility dimension. It allows us to do something like
(measure,[Dim Date Calculations].[Date Calculations].[Prior Period]) and it gives use the prior period of measure for the current member of dim date (month goes back 1 month, quarter goes back 3 months, semester goes back 6 mo, year goes back 12 mo). It's very clean, accurate and pretty fast.
-- Fiscal Month
Scope( [Dim Date].[Month Key].[Month Key].members);
-- Prior Period
Scope([Dim Date Calculations].[Date Calculations].[Prior Period]);
this =
( [Dim Date].[Month Key].CurrentMember.PrevMember
,[Dim Date Calculations].[Date Calculations].[Current]
);
END scope;
End Scope;
-- Fiscal Quarter
Scope( [Dim Date].[Fiscal Quarter].[Fiscal Quarter].members);
-- Prior Period
SCOPE( [Dim Date Calculations].[Date Calculations].[Prior Period]);
THIS = ( [Dim Date].[Fiscal Quarter].CurrentMember.PrevMember
,[Dim Date Calculations].[Date Calculations].[Current]
);
END SCOPE;
END SCOPE;
-- Fiscal Semester
Scope( [Dim Date].[Fiscal Semester].[Fiscal Semester].members);
-- Prior Period
SCOPE( [Dim Date Calculations].[Date Calculations].[Prior Period]);
THIS = ( [Dim Date].[Fiscal Semester].CurrentMember.PrevMember
,[Dim Date Calculations].[Date Calculations].[Current]
);
END SCOPE;
End Scope;
-- Fiscal Year
Scope( [Dim Date].[Fiscal Year].[Fiscal Year].members);
-- Prior Period
SCOPE( [Dim Date Calculations].[Date Calculations].[Prior Period]);
THIS =
( [Dim Date].[Fiscal Year].CurrentMember.PrevMember
,[Dim Date Calculations].[Date Calculations].[Current]
);
END SCOPE;
End Scope;
[disclaimer I'm working for icCube]
Scope is not part of icCube, not yet planned. It's a tricky feature that didn't naturally fit into icCube's architecture (see discussion below, later ... ). The strength of icCube is also the agility of it's R&D team, do not hesitate to contact them directly they will me more than happy to improve and add features.
In icCube there are some functionalities that are different from classical MDX server that might be useful, it's Categories, SubCubes and the eval function.
Categories. Allows for defining a new member that behaves like classical members. This new member can be defined as a set of members or as a subcube. For example here we can define a [Top10] category member as our 10 most important customers :
CATEGORY MEMBER [Top10] as TopCount( [Customers], 10, ([Measures].[Sales],[2015]) )
-> so later on ( [Top10], [Sales] ) will return the sales of this top10 customers
SubCubes, allows defining richer logical relations on members as a set of tuples. icCube implements SubCubeComplement, SubCubeIntersect,SubCubeOthers, SubCubeSymDifference, SubCubeUnion and SubCubeMinus. So calculating all without France (it's trivial here, but think on hierachies with many-to-many relations)
SubCubeMinus([Geography].[Geo].[All], [Geography].[Geo].[France] )
The Eval function, allows for evaluating an expression on a subCube. Here is a trivial example doing the sum using the union :
MEMBER [US+CH] AS Eval( SubCubeUnion( [Switzerland], [United States]) , [Amount])
Last but not least, for the dates function you can define Function in icCube that you can reuse in your MDX, no need to copy&paste everywhere :
CREATE FUNCTION square( Value val ) AS val * val
and combine with CompactSet for a faster evaluation on dates periods (if there are no m2m relations on this dimension) or call some Java functions (you've to activate this module that is off by default).
--------------------- Scope ---------------------------
Warning : Comments might be obsolete as my understanding of scope is the one of a few years ago. Let's go :
Scope is a nice functionality but there are some drawbacks that you can check in Chris Webb's presentation ( link ), check from 47:30 for about 5 minutes.
The issues where/are :
Somehow a scope allows to define a new value for a subcube (remember a subcube might be a single indivisible cell as well as thousands of them)
1) Scopes allows for defining the value of a subcube but what do you do if you want a 'part' of this subcube ?
2) What happens if two scopes collide (intersection is not empty) ?
And all this mixed with security, many-to-many relations, subqueries and set where clauses.
We're not SSAS specialist and it's possible that with a better understanding we try again to implement a clean solution but for know we believe there are other ways solving the problems (for example using calc. members or writebacks).
hope it helps.

SSAS MDX Calculated Measure Based on Related Dimension Attribute Value

I have a measure [Measures].[myMeasure] that I would like to create several derivatives of based on the related attribute values.
e.g. if the related [Location].[City].[City].Value = "Austin" then I want the new calculated measure to return the value of [Measures].[myMeasure], otherwise, I want the new calculated measure to return 0.
Also, I need the measure to aggregate correctly meaning sum all of the leaf level values to create a total.
The below works at the leaf level or as long as the current member is set to Austin...
Create Member CurrentCube.[Measures].[NewMeasure] as
iif(
[Location].[City].currentmember = [Location].[City].&[Austin],
[Measures].[myMeasure],
0
);
This has 2 problems.
1 - I don't always have [Location].[City] in context.
2. When multiple cities are selected this return 0.
I'm looking for a solution that would work regardless of whether the related dimension is in context and will roll up by summing the atomic values based on a formula similar to above.
To add more context consider a transaction table with an amount field. I want to convert that amount into measures such as payments, deposits, return, etc... based on the related account.
I don't know the answer but just a couple of general helpers:
1 You should use IS rather than = when comparing to a member
2 You should use null rather than 0 - 0/NULL are effecitvely the same but using 0 will slow things up a lot as the calculation will be fired many more times. (this might help with the second section of your question)
Create Member CurrentCube.[Measures].[NewMeasure] as
iif(
[Location].[City].currentmember IS [Location].[City].&[Austin],
[Measures].[myMeasure],
NULL
);

Slow MDX Custom Distinct Count Formula

I have a question related to creating a (more efficient) custom Distinct Count Measure using MDX.
Background
My cube has several long many to many relationship chains between Facts and Dimensions and it is important for me to be able to track which members in certain Dimensions do and do not relate to other Dimensions. As such, I have created a "Not Related" record in each of my dimension tables and set those records' ID values to -1. Then in my intermediate mapping fact tables I use the -1 ID to connect to these "Not Related" records.
The issue arises when I try to run a normal out-of-the-box distinct count on any field where the -1 members are present. In the case that a -1 member exists, the distinct count measure will return a result of 1 more than the true answer.
To solve this issue I have written the following MDX:
CREATE MEMBER CURRENTCUBE.[Measures].[Provider DCount]
AS
//Oddly enough MDX seems to require that the PID (Provider ID) field be different from both the linking field and the user sliceable field.
SUM( [Providers].[PID Used For MDX].Children ,
//Don't count the 'No Related Record' item.
IIF( NOT([Providers].[PID Used For MDX].CURRENTMEMBER IS [Providers].[PID Used For MDX].&[-1])
//For some reason this seems to be necessary to calculate the Unknown Member correctly.
//The "Regular Provider DCount Measure" below is the out-of-the-box, non-MDX measure built off the same field, and is not shown in the final output.
AND [Measures].[Regular Provider DCount Measure] > 0 , 1 , NULL )
),
VISIBLE = 1 , DISPLAY_FOLDER = 'Distinct Count Measures' ;
The Issue
This MDX works and always shows the correct answer (yeah!), but it is EXTREMELY slow when users start pulling Pivot Tables with more than a few hundred cells that use this measure. For less than 100 cells, the results are nearly instantaneously. For a few thousand cells (which is not uncommon at all), the results could take up to an hour to resolve (uggghhh!).
Can anyone help show me how to write a more efficient MDX formula to accomplish this task? Your help would be GREATLY appreciated!!
Jon Oakdale
jonoakdale#hotmail.com
Jon
You can use predefined scope to nullify all unnecessary (-1) members and than create your measure.
SCOPE ([Providers].[PID Used For MDX].&[-1]
,[Measures].[Regular Provider DCount Measure]);
THIS = NULL;
END SCOPE;
CREATE MEMBER CURRENTCUBE.[Measures].[Provider DCount]
AS
SUM([Providers].[PID Used For MDX].Children
,[Measures].[Regular Provider DCount Measure]),
VISIBLE = 1;
By the way, I used in my tests [Providers].[PID Used For MDX].[All].Children construction since don't know, what is dimension / hierarchy / ALL-level in your case. It seems like [PID Used For MDX] is ALL-level and [Providers] is name of dimension and hierarchy, and HierarchyUniqueName is set to Hide.

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])