What are the differences between a DEFAULT time dimension and another time dimension ?
Is it just like for the default measure, i.e. used if no measure is mentionned in a MDX?
Can we do exactly the same things with a non-default time dimension ?
I'm thinking about Evolutions, running sums, avg, dtXXX functions, ytd function.
The DEFAULT time dimension is the one that is going to be used in custom rollup aggregation (www) when you do not define any hierarchy and a few MDX time functions when no hierarchy is defined (Ytd, Qtd, Mtd, Wtd ...).
Apart from that there is no difference with a regular time dimension.
Related
Scenario
Designing a Star Diagram for an OLAP environment for the process Incident Management. Management requests to be able to both filter on SLA status (breached, achieved or in progress) and being able to calculate the percentage of sla achieved vs breached. Reporting will be done through in Excel/SSRS through SSAS (tabular).
Question
I’m reasonable inexperienced in designing for an OLAP environment. I know my idea will work but I’m concerned this is not the best approach.
My idea:
SLA needs to be both a measure and a dimension.
DimSLA
…
(Nullable bool) Sla Achieved -> Yes=True, No=False, and InProgress=NULL
…
FactIncident
…
(Nullable Integer) Sla Achieved Yes=1,No=0 and In Progress=NULL
…
Then in SSAS, publish a calculated percentage field which averages FactIncident-SlaAchieved.
Is this the right/advisable way to do it?
As you describe it, "SLA achieved" should be an attribute, as you want to classify by it, not sum it. The only thing you want to sum or aggregate would be other measures (maybe an incident count) under the condition that the "SLA achieved" attribute has certain values like "achieved" or "not achieved". This is the main rule in dimensional design: Things you use for classifying or break down are attributes, and things that you calculate are measures. There are a few cases where you need a column for both, but not many.
Do not just use a boolean value. Use a string value easily understand by users like the texts "SLA achieved", "SLA not achieved", "in progress". This makes it much more easy for non technical users to use the cube. In case you use this in a dimension table , there would be just three records with the strings, and the fact table would reference them with maybe a byte foreign key, hence more meaningful texts do not use up millions of bytes.
I have a calculated member that looks like this:
Asian Weighted = ([Measures].[Asian] * [Measures].[Population])
My MDX query looks like this:
WITH
MEMBER [Measures].[AsianPop] AS
(([Measures].[Asian Weighted], [Jurisdiction.BTA].[BTA].&[51]) / ([Jurisdiction.BTA].[BTA].&[51], [Measures].[Population]))
SELECT
{[Measures].[AsianPop]} ON 0
FROM
[Selection Statistics]
The problem is in the numerator. Asian and Population are both SUMMED before they are multiplied together. Is there a straightforward way to do a weighted average in MDX?
The solution that you described in your comment - pre-caclulating the measure to sum - is the best approach. In theory, you could implement the correct calculation purely in MDX, but this is complex and in many cases - at least in Analysis Services, I have no experience with Mondrian - really slow. You would have to instruct the MDX engine explicitly to do the multiplication on leaf level, and then aggregate. You could use functions like Leaves or Descendants to go to leaf level. You would have to think about the attributes for which you need to go down to leaf level, and for which attributes this may not be necessary. My assumption - as far as Analysis Services is concerned - is that as this uses a custom aggregation, all the built in aggregations which make the cube fast are not used.
How do I create custom rollup types in icCube?
Say, I need WAvg (which is already implemplemented there) instead of plain Avg function. But I it is not on the dropdown list in measure creation form. What should I do now?
Alexander, I assume you're talking about the cube builder.
The weighted-average is not available in the list of available aggregation types because there's no straitforward way to implement it at cube level. Aggregation types available for standard measures are simple calculations. Those calculation are meant to be very fast for millions of rows. You've two kinds of average available for standard measures : 'average on leafs(rows)' and 'average on children', which might be near what you're looking for.
In the case of a weighted average you have to create a calculated measure: you need to defined the values to "weight" your underlying measure against. The documentation weighted-average is giving several examples.
Is there such a thing as a constant in SSAS?
Example (this is really happening where I'm at) everyone agrees that gigs to mb be converted by 1000 (not 1024) and tb to mb by 1000000.
Where would you store a number like that used across the board?
If it's inside the cube, could you create a calculated member that stores it? Define it in the cube's calculation script, it's fine with constants in there.
In cube calculation script:
CREATE MEMBER CURRENTCUBE.Measures.MBtoGigs AS 1000
Query against the cube:
SELECT Measures.MBtoGigs ON COLUMNS FROM [Cube]
One possible pitfall I would point out, is that using constants like this can alter the way you'd expect the NON EMPTY behaviour to work in your queries - As a constant is never 'empty'.
Having said that, you can define you own non-empty-behaviour for calculated measures, so remember to try that with any calculated measures that involve constants if you experience any issues.
where\how do you need to use it?
you can always create a fact table with a column with that value (1000), whitch will become a measure group, and set the aggregation type on the measure with to "lastNonempty".
Since this value is on its own MG it can be easly used on the expression property of another measure on a different MG
I have a SSAS cube in which there is a measure that needs to be allocated via a percentage located in another measure. I have all this set up as a Measure Expression in my "Equity Amount" measure and it works great.
My problem is that this "Equity Amount" measure is actually a snapshot so I would need it to aggregate using the LastChild function. It turns out that you cannot have a measure expression in a semi additive measure so i'm trying to fake the LastChild function in MDX.
I've seen a lot of examples everywhere on the web and all but none of them talk about having multiple hierarchies in the date dimension. I have both "calendar Year" and "Fiscal Year" hierarchies.
My MDX works for one hierarchy but as soon as I scope for the second hierarchy, the first one gets overwritten. I'm guessing I need to treat both hierarchies in a single statement but am having a real tough time getting it to work.
Here is my MDX for one hierarchy. Can anyone help modify it for multiple hierarchies or is there any other way to solve my problem ?
Scope([Measures].[Equity Value]);
This = iif(isleaf([Calendar].[By Calendar Year].CurrentMember),
[Measures].[Equity Value],
([Calendar].[By Calendar Year].CurrentMember.LastChild,[Measures].[Equity Value]));
End Scope;
David,
1) You're using scope as a calculated member. You can get rid of your iif by declaring the scope working only in a sub-cube :
scope ([Measures].[Equity Value],[Calendar].[By Calendar Year].levels(0).... )
This = (the expression)
2) Not sure to understand your problem but a tuple with two members of two hierarchies of the same dimension can be null by construction: As an example your first day of the calendar (1/1/2010) and the first day of your fiscal calendar (e.g. 1/6/2020) are not the same day so actually null. Two hierarchies of a same dimension are only ways of representing the same coordindates (here days), you're doing an intersection by declaring a tuple.
Not sure I'm helping you...
Thanks for trying! I understand what you mean (I think). MDX is one tough language!
I ended up doing the allocation via the view that is the source for my measure and keeping the LastChild aggregation function for the measure. In the end, it is much easier and also is better for query performance.
Thanks anyway :)