510 likes | 634 Views
Fun with Scoped Assignments. Chris Webb www.crossjoin.co.uk. Who Am I?. Chris Webb chris@crossjoin.co.uk Independent Analysis Services and MDX consultant and trainer Author: “MDX Solutions” and “Expert Cube Development with SSAS 2008” SQL Server MVP Blogger: http://cwebbbi.wordpress.com.
E N D
Fun with Scoped Assignments Chris Webb www.crossjoin.co.uk
Who Am I? • Chris Webb chris@crossjoin.co.uk • Independent Analysis Services and MDX consultant and trainer • Author: “MDX Solutions” and “Expert Cube Development with SSAS 2008” • SQL Server MVP • Blogger: http://cwebbbi.wordpress.com
Agenda • What are scoped assignments and why should I use them? • Defining subcubes • Assignments to calculated measures • Complex subcubes • Assignments to real measures and aggregation • FREEZE and IF • Assigning to properties
What are scoped assignments? • Scoped assignments allow you to overwrite the value of cells inside your cube • Contrast this with calculated members, which extend the space of the cube • They are defined on the MDX Script of your cube, on the Calculations tab in BIDS
Why should I use them? • Among other things, they allow you to: • Make calculations behave in different ways in different parts of the cube • Break up logic for complex calculations into more comprehensible parts • Perform calculations at low levels of granularity that can then be aggregated up very efficiently • They are often the most efficient way of writing certain calculations
Defining subcubes • Scoped assignments have two parts: • The subcube definition - the part of the cube whose value will be overwritten • The assignment - the new value written to the subcube • There are two ways of defining a subcube • Direct assignment • The SCOPE statement
Direct assignment syntax • Direct assignment uses the following syntax:(subcube definition) = value; • For example:([Measures].[Internet Sales Amount])=1; • I prefer not to use it, because this syntax can very quickly become unreadable
SCOPE statements • SCOPE statements take the form:SCOPE(subcube definition); THIS = value;END SCOPE; • For example:SCOPE([Measures].[Internet Sales Amount]); THIS=1;END SCOPE;
Nesting SCOPE statements • The advantage of using SCOPE statements is that you can nest several to build up complex subcubes, eg:SCOPE([Measures].[Internet Sales Amount]); SCOPE([Date].[Calendar Year].[Calendar Year].MEMBERS); THIS=1; END SCOPE;END SCOPE; • This has obvious benefits for readability • You can also make assignments at different levels within the nesting
Subcube definition rules • A subcube definition is made up of one or more sets of members from different hierarchies • These sets can be included in a single SCOPE statement, or several nested SCOPE statements • They define the boundaries of the subcube on different hierarchies
Subcube definition rules • There are limitations on the shape of a subcube you can assign to • If you break them, you will get the infamous ‘arbitrary shaped set’ error • These are that a set of members can only contain: • One member from an attribute hierarchy • Several members from an attribute hierarchy, not including the All Member • Every member from an attribute hierarchy, including the All Member
Subcube definition best practices • Best to ignore user hierarchies • Include sets of members from different hierarchies on the same dimension in the same SCOPE statement • Avoids problems with attribute overwrite • Specifically scope on one or more measures • Unless you really do want to scope on all measures • Even then can cause problems if you add new measures/measure groups in the future
Assignments to calculated members • Scoped assignments can be made to calculated members as well as real members • In fact, assignments to calculated measures are probably the most common use • Calculated measures don’t aggregate up… • You should not assign to a set containing both calculated members and real members • In most cases you can’t do this
Complex subcubes • Often we will want to scope on several attributes in a dimension at once • Eg all calendar year attributes, or all financial year attributes • To do this, you need to know your attribute relationships • The rule is: • For the lowest attribute, scope on all members in the hierarchy including the All Member • For the highest attribute, scope on all members in the hierarchy except the All Member
Controlling area of calculation • Calculated measures often need to do different things in different places • Some calculations should not be done at all in some places • Eg you may not want to see a 3 month moving average at the year level • Eg previous period growth for your first year with data • Some calculations may need different logic in different part of the cube • Eg tax calculations could be different every year • Eg calculation logic may change for business reasons, but you want to see the older algorithm used for historical data • Eg previous year growth could mean ‘previous financial year’ or ‘previous calendar year’ depending on which hierarchy you’re using
Assignments to real measures • When you assign to real (ie not calculated) measures, any values you assign will automatically aggregate up through the cube • This in turn may overwrite previous assignments that you have made • …and make it very difficult to know what’s going on…
Special cases for aggregation • In some cases, a cell can be calculated in two different ways from previous assignments • When this happens, the assignment made last in the script will take precedence • This is the ‘last pass wins’ rule • Also, when there are unary operators, these will always take precedence • This is the ‘closest pass wins’ rule
Uses for assignments to real measures • There are several practical uses for making assignments to real measures: • Replacing custom member formulas, so you can have all your code in the MDX Script • Always scope on members on the lowest level first then work upwards • Performing calculations at a low level of granularity and them aggregating the results • Eg currency conversion
Assignment ‘Passes’ • Each new assignment creates a new ‘pass’ in the script • Think of the cube like an onion, with each new pass as a new layer in the skin on the outside • When you refer to an existing cell value in an assignment, you are actually referring to that cell value in the previous pass • Therefore avoiding infinite recursion
The FREEZE statement • When you assign a value to a cell, you create something like a pointer to that cell • So you don’t copy the new values assigned subcube • So if the values the assignment points to subsequently change, the values in your subcube will change • Using the FREEZE statement on a subcube stops this happening • Do not use FREEZE as a substitute for correct ordering of calculations • There is a performance overhead for using it!
The IF statement • Conditional assignments can be made using the IF statement:SCOPE(MEASURES.SALES); IF MEASURES.SALES>100 THEN THIS=0 END IF;END SCOPE; • Note that even when the condition evaluates to false and no assignment is made, a new pass is created
Assigning cell property values • The following cell property values can also be directly assigned to: Format_String, Non_Empty_Behavior, Language, Font_Size, Font_Flags, Font_Name, Fore_Color, Back_Color • Error values can be assigned to cells using the ERROR statement • Useful when: • A single measure holds values in different currencies which should be formatted differently depending on the currency • Debugging complex subcube definitions