I'm rather new to SSAS and am completely stumped on how to solve this problem. I have a dimension called Thresholds. Within the Thresholds dimension there are the following Members:
[Threshold Year], [Threshold1 Amount], [Threshold2 Amount], [Threshold3 Amount]
I also have a measures called [Qualifying Commission], [Tier1 Amount], [Tier2 Amount], [Tier3 Amount]
On top of that there is also a time dimension called [Statement Dates]
So basically here is what I am trying to do. I want to create a calculated member that when an end user selects a time frame from [Statement Dates] I want to sum up [Qualifying Commission] and check it against the threshold amounts for the corresponding year. If it is greater than [Threshold1 Amount], I want it to return the [Tier1 Amount] measure with the same logic applying to thresholds 2 and 3.
Can somebody give me a road map on what I need to do? If I need to restructure the data in the underlying database to make this work then that would be really helpful to know. Thanks in advance for the help.
Well, let's assume that [Qualifying Commission] is an additive measure, meaning the sum is taken care of for us by SSAS.
Essentially, we just need to find whatever year we're in under [Statement Dates] to get our thresholds.
So, let's break it into some chunks. The first thing we do is to find our right [Threshold Year]:
create set [Current Threshold] as
iif([Statement Dates].[YQM].CurrentMember IS [All]
,[Threshold Year].[All]
,StrToSet("[Threshold Year].[" +
Ancestor([Statement Dates].[YQM].CurrentMember
, [Statement Dates].[YQM].[Year]).Name +
"]"))
Next, we'll apply this threshold to get the right number:
create member currentcube.[Measures].[Threshold Amount] as
case
when [Qualifying Commission] >
[Current Threshold].Item(0).Properties("Threshold1 Amount") then
[Measures].[Tier1 Amount]
when [Qualifying Commission] >
[Current Threshold].Item(0).Properties("Threshold2 Amount") then
[Measures].[Tier2 Amount]
when [Qualifying Commission] >
[Current Threshold].Item(0).Properties("Threshold3 Amount") then
[Measures].[Tier3 Amount]
else 0
end
And voila, you're cooking with gas.
You should also look into using the scope operator. It can help performance when you need to implement conditional sums.
Scope operator From MSDN
Related
I am trying to do Cumulative Sum/ Running Total using the function below so the user can use any date level, but the requirement is to ignore some of the attributes from the calculation.
Function used:
SUM(NULL:Axis(1).Item(0).Item(Axis(1).Item(0).Count-1).Hierarchy.CurrentMember, [Measures].[ Number of Ticket])
Example:
The table below shows the Cumulative Sum as expected
Example - 1
Here by adding another attribute, Program Remaining, as shown below, its changes the Cumulative behavior, Because Excel will add that attribute to the grouping so it reset the cumulative sum:
Example - 2
Is there a way that I can exclude the Program Remaining attribute from the calculation (I have another 4 attributes that I want to exclude) so that the cumulative can be increased just like the first table even with adding these attribute.
I really appreciate any help
Try using the below sample query
with
member
[Measures].[Internet Sales AmountRunningtotal]
as
case when [Measures].[Internet Sales Amount] = null then null
else
sum({[Product].[Subcategory].firstchild:[Product].[Subcategory].currentmember},[Measures].[Internet Sales Amount])
end
select {[Measures].[Internet Sales Amount],
[Measures].[Internet Sales AmountRunningtotal]
} on columns,
non empty
([Date].[Calendar Year].[Calendar Year],[Date].[Calendar Quarter of Year].[Calendar Quarter of Year],
[Product].[Category].[Category],[Product].[Subcategory].[Subcategory])
on
rows
from
[Adventure Works]
So I explored the sample sent, Your only solutions is to keep the date in the inner most position, your query qouted above will break if you are not using entire members of an attribute.
I would like to calculate average using a numeric value in dimension instead of using a measure. Is that possible?
Also I would like to know whether average can be calculated with a dimension that is categorized with another dimension.
Here is the Avg function onMSDN: https://msdn.microsoft.com/en-us/library/ms146067.aspx
It gives several examples of using it with numeric expressions such as the following:
WITH MEMBER Measures.[Avg Gross Profit Margin] AS
Avg(
Descendants(
[Ship Date].[Fiscal].CurrentMember,
[Ship Date].[Fiscal].[Date]
),
Measures.[Gross Profit Margin]
)
SELECT
Measures.[Avg Gross Profit Margin] ON COLUMNS,
[Ship Date].[Fiscal].[Fiscal Year].[FY 2003].Children ON ROWS
FROM
[Adventure Works]
I need to product a report from my cube that looks something like the following.
(dummy data)
Where it lists sales and gross profit for today, this week, the period and year to date across the products category.
My cube is setup as follows
A date dimension
And the cube itself
Currently I have not implemented the product category pieces.
I'm struggling with how to write an MDX query that can return the sales/gross profit for a single day and then week and so on.
I can return it by itself like so
SELECT {[Measures].[Gross Profit],[Measures].[Price]} ON COLUMNS
From [Cube]
WHERE [Date].[Date Key].[2015-04-22];
and so on for the other various types (week etc), but I'm unsure as how to apply the where filter to the columnn itself rather than the overall query, or if this is even the correct way to do it and I should be making multiple MDX calls that I then compose in my app that will use this.
Can anyone give me a pointer in the right direction here?
EDIT: Seems to mostly work using the approach #Akshay Rane described however I cannot get one of my measures to work
MEMBER [This Week] as
(PeriodsToDate([Date].[Fiscal Week Date].[Fiscal Week],StrToMember('[Date].[Fiscal Week Date].[Date Key].&[' + '20140401' + ']'))
,[Measures].[Merchandise Gross Profit])
Gives me an error:
The function expects a string or numeric expression for the argument. A tuple set expression was used.
Any pointers here?
You will have to create separate Calculated Members for each time interval you want to aggregate the data upon.
This can be done in [Adventure Works] cube as follows.
WITH
MEMBER [Today] as
([Measures].[Internet Sales Amount], [Date].[Date].CURRENTMEMBER)
MEMBER [Last Week] as
AGGREGATE (
{ [Date].[Date].CURRENTMEMBER.lag(6) : [Date].[Date].CURRENTMEMBER }
, [Measures].[Internet Sales Amount]
)
SELECT
{ [Today], [Last Week] } ON 0,
{ ([Product].[Product Categories].[Category], [Date].[Date].[Date]) } ON 1
FROM
(
/*FILTERING ON SPECIFIC DATE USING SUBCUBE*/
SELECT [Date].[Date].&[20070715] ON 0
FROM [Adventure Works]
)
If you can take the different levels of date from the same user hierarchy then something like this is possible:
SELECT
{
[Date].[Calendar].[Month].&[2006]&[7]
,[Date].[Calendar].[Date].&[20050220]
}
*
{
[Measures].[Order Quantity]
,[Measures].[Internet Sales Amount]
} ON COLUMNS
,{[Product].[Category].Children} ON ROWS
FROM [Adventure Works];
The above produces results like this:
I wrote an mdx script showing period on period growth for Internet Sales Amount, and it all works fine.
We are using an interface, where you can place a slicer so that user can choose what dimension of date.Calendar he is interested in, i.e.whatever dimension of Date.Calendar the user decides to choose (Quarter, Month, Year) it will correctly look at previous member. Now, im trying to obtain the same for Measure - i.e. i want it to be flexible dependant on what measure the user will choose in the slicer ( i.e. Internet tax Amount).
I cant think of a way of creating a previous member with measure being flexible...
WITH
MEMBER [Measures].[Internet Sales Amount PP] AS
(
[Date].[Calendar].CurrentMember.Prevmember,
[Measures].[Internet Sales Amount]
)
MEMBER [Measures].[Period on Period Grwth %] AS
IIF (
[Measures].[Internet Sales Amount PP] = 0,
'N/A',
([Measures].[Internet Sales Amount]-[Measures].[Internet Sales Amount PP]) /[Measures]. [Internet Sales Amount PP]
)
,FORMAT_STRING = "percent"
SELECT
[Date].[Calendar].[Month] ON ROWS,
{[Measures].[Internet Sales Amount],
[Measures].[Internet Sales Amount PP],
[Measures].[Period on Period Grwth %]} ON COLUMNS
FROM [Adventure Works]
If you happen to use SSRS, you can add a parameter to absorb the measure selected in the drop down from front end. We host SSRS in SharePoint environment and this is how we do it.
WITH
MEMBER [Measures].[Measure Growth PP] AS
(
[Date].[Calendar].CurrentMember.Prevmember,
strtomember('[Measures].'+ #MeasureSelected)
)
MEMBER [Measures].[Period on Period Grwth %] AS
IIF (
[Measures].[Measure Growth PP] = 0,
'N/A',
(strtomember('[Measures].'+ #MeasureSelected)-[Measures].[Measure Growth PP]) /
[Measures].[Measure Growth PP]
)
,FORMAT_STRING = "percent"
SELECT
[Date].[Calendar].[Month] ON ROWS,
{strtomember('[Measures].'+ #MeasureSelected),
[Measures].[Measure Growth PP],
[Measures].[Period on Period Grwth %]} ON COLUMNS
FROM [Adventure Works]
I have to count something in a strange way, and it works in most cases -- both at leaves and at higher levels of aggregation across multiple dimensions. But it doesn't give correctly aggregated values for one specific dimension.
What I have at the moment is ...
CREATE MEMBER CURRENTCUBE.[Measures].[Active Commitments]
AS NULL,
FORMAT_STRING = '#,#',
VISIBLE = 1;
SCOPE (DESCENDANTS([Date Dimension].[Fiscal Year Hierarchy],,AFTER));
[Measures].[Active Commitments] =
iif([Constituent Activity].[Type].currentMember.Properties("Name")="Correspondence",
sum(([Commitment Dates].[Start Date], NULL: [Date Dimension].[Fiscal Year Hierarchy]), [Measures].[Commitment Count]),
sum(([Commitment Dates].[First Funded Date], NULL: [Date Dimension].[Fiscal Year Hierarchy]), [Measures].[Commitment Count]))
- sum(([Commitment Dates].[Stop Date],[Commitment].[Was Commitment Ever Active].[Sometime Active], NULL: [Date Dimension].[Fiscal Year Hierarchy]), [Measures].[Commitment Count]);
END SCOPE;
SCOPE (DESCENDANTS([Date Dimension].[Fiscal Year Hierarchy],,AFTER));
<Similar to above>
As you can see, the complexity is that one type of "commitment" commences at the [Start Date] and others commence at the [First Funded Date].
This fails whenever multiple members of [Constituent Activity] are selected because in such cases the use of currentMember in the SCOPE statement is invalid. For example, the following MDX executes successfully but outputs #Error --
select
[Measures].[Active Commitments] on columns
,[Date Dimension].[Fiscal Year Hierarchy].[Fiscal Year].&[2011\12] on rows
from Compass3
where
{[Constituent Activity].[Description].[XYZ]
,[Constituent Activity].[Description].[ABC]}
I think what I need to encode within the SCOPE statement is the recursive ...
if a single member of [Constituent Activity] is current
then use the calc as defined above
else use [Measures].[Active Commitments] = sum(all selected members of [Constituent Activity], [Measures].[Active Commitments])
... but how would I write that?
Do you have control all the way back to the data warehouse/data source view? Can you add a calculated field to your fact table, so you have [Commitment Active Date] at the cell level? Then you could do much simpler counts in the cube.
I have found that enforcing business rules and doing business calculations in the data warehouse is more efficient and easier in the long run.