MTD Function not working with SCOPE - ssas

SCOPE ([Measures].[Net IMS Volume]);
( [Time].[Time Calculations].[MTD] )
= SUM(
MTD([Time].[Time Hierarchy 1].CURRENTMEMBER)
,[Time].[Time Calculations].[Current Time]
);
END SCOPE;
I was expecting my MTD to be displayed across the dates of the month. but the result is that I just get data at the Month Level.
When I do the same thing over at SSMS w/ the ff.:
WITH MEMBER [Time].[Time Calculations].MIKE2 AS
SUM
(
MTD([Time].[Time Hierarchy 1].CURRENTMEMBER)
,[Time].[Time Calculations].[Current Time]
)
SELECT
{
([Time].[Time Calculations].[MTD],[Measures].[Net IMS Volume])
,([Time].[Time Calculations].MIKE2,[Measures].[Net IMS Volume])
} ON 0
,[Time].[Time Hierarchy 1].[Date] ON 1
FROM [My Cube];
I get data at Date Level. I'm experiencing this on YTD function also.

Your time dimensions may not be typed correctly. Specific typing is required for the YTD and MTD to function as expected.
MSDN reference to YTD function: https://msdn.microsoft.com/en-us/library/ms146039.aspx
In the "remarks" section of the definition:
If a member expression is not specified, the default is the current
member of the first hierarchy with a level of type Years in the first
dimension of type Time in the measure group.
The Ytd function is a shortcut function for the PeriodsToDate function where the Type
property of the attribute hierarchy on which the level is based is set
to Years. That is, Ytd(Member_Expression) is equivalent to
PeriodsToDate(Year_Level_Expression,Member_Expression). Note that this
function will not work when the Type property is set to FiscalYears.
You could test if this is your problem by converting to the use of PeriodsToDate:
WITH MEMBER [Time].[Time Calculations].MIKE2 AS
SUM
(
PeriodsToDate(
[Time].[Time Hierarchy 1].[Month Level]
, [Time].[Time Hierarchy 1].CURRENTMEMBER
)
,[Time].[Time Calculations].[Current Time]
)
SELECT
{
([Time].[Time Calculations].[MTD],[Measures].[Net IMS Volume])
,([Time].[Time Calculations].MIKE2,[Measures].[Net IMS Volume])
} ON 0
,[Time].[Time Hierarchy 1].[Date] ON 1
FROM [My Cube];

Related

How to mimic SQL subtraction of results from two different queries in mdx

I wanted to do the trend analysis between the dates. For an instance current date- 30 days
30-60 days and so on.Below is the snippet of comparable sql query but same I wanted to do in MDX.
SQL
SELECT
ROUND
(
(
(
(
SELECT
SUM(del_pri_impr)
FROM
reporting.so_sli_calc_val a,
reporting.user_group_tenant b,
reporting.salesorder c
WHERE
created_on BETWEEN DATE(now()-30) AND DATE(now())
)
-
(
SELECT
SUM(del_pri_impr)
FROM
reporting.so_sli_calc_val a,
reporting.user_group_tenant b,
reporting.salesorder c
WHERE
created_on BETWEEN DATE(now()-60) AND DATE(now()-30)
)
)
/
(
SELECT
SUM(del_pri_impr)
FROM
reporting.so_sli_calc_val a,
reporting.user_group_tenant b,
reporting.salesorder c
WHERE
created_on BETWEEN DATE(now()-60) AND DATE(now()-30)
) *100
)
,
0
) AS trend
MDX:
WITH
SET [~FILTER] AS
{[Created_Date.Created_Hir].[Created_On].[2014-04-01]:[Created_Date.Created_Hir].[Created_On].[2014-04-30]}
SET [~ROWS] AS
{[Sales Order Attributes SO.Sales_order].[Sales Order ID].Members}
SELECT
NON EMPTY {[Measures].[CONT_AMT_GROSS], [Measures].[CONT_AMT_NET]} ON COLUMNS,
NON EMPTY [~ROWS] ON ROWS
FROM [SALES_ORDER]
WHERE [~FILTER]
As of now I have hard coded the dates, that will come from parameters.
I am facing difficulty in creating the second set and how to do subtraction between two sets in MDX.
You already have the logic on how to obtain sets of date corresponding to "last 30 days from now" and "last 60 to last 30 days from now". So, I am going to skip that part.
NOTE - You would have to use the parameter values while building these sets.
What you want to do here is first find the values corresponding to these sets of dates and then perform operations on them.
You can proceed like this -
WITH
SET [~FILTER] AS
{[Created_Date.Created_Hir].[Created_On].[2014-04-01]:[Created_Date.Created_Hir].[Created_On].[2014-04-30]}
SET [~ROWS] AS
{[Sales Order Attributes SO.Sales_order].[Sales Order ID].Members}
SET [Last30Days] AS
...
SET [Last60ToLast30Days] AS
...
MEMBER [~Last30Days - Now] AS
Aggregate
(
[Last30Days],
[Measures].[SomeMeasure]
)
MEMBER [~Last60Days - Last30Days] AS
Aggregate
(
[Last60ToLast30Days],
[Measures].[SomeMeasure]
)
MEMBER [~Measure] AS
([~Last30Days - Now]-[~Last60Days - Last30Days] )/([~Last60Days - Last30Days] * 100), format_string = '#,##0'
SELECT
NON EMPTY {
[Measures].[CONT_AMT_GROSS],
[Measures].[CONT_AMT_NET],
[~Measure]
} ON COLUMNS,
NON EMPTY [~ROWS] ON ROWS
FROM [SALES_ORDER]
Format_String takes care of rounding.
Not sure if I totally agree with Sourav's answer as I think some form of aggregation will be needed; creating tuples with sets in them may raise an exception.
Here is a simple model, against AdvWrks, that is tested and will do a subtraction for you:
WITH
SET [Set1] AS
[Date].[Calendar].[Date].&[20060301]
:
[Date].[Calendar].[Date].&[20070308]
SET [Set2] AS
[Date].[Calendar].[Date].&[20070308]
:
[Date].[Calendar].[Date].&[20080315]
MEMBER [Date].[Calendar].[All].[Set1Agg] AS
aggregate([Set1])
MEMBER [Date].[Calendar].[All].[Set2Agg] AS
aggregate([Set2])
MEMBER [Date].[Calendar].[All].[x] AS
(
[Date].[Calendar].[All].[Set1Agg]
,[Measures].[Internet Sales Amount]
)
MEMBER [Date].[Calendar].[All].[y] AS
(
[Date].[Calendar].[All].[Set2Agg]
,[Measures].[Internet Sales Amount]
)
MEMBER [Date].[Calendar].[All].[x-y] AS
[Date].[Calendar].[All].[x] - [Date].[Calendar].[All].[y]
SELECT
{
[Date].[Calendar].[All].[x]
,[Date].[Calendar].[All].[y]
,[Date].[Calendar].[All].[x-y]
} ON 0
,[Product].[Category].[Category] ON 1
FROM [Adventure Works];
Reflecting against your code maybe something like the following:
WITH
SET [Set1] AS
[Created_Date.Created_Hir].[Created_On].[2014-04-01]
:
[Created_Date.Created_Hir].[Created_On].[2014-04-30]
SET [Set2] AS
[Created_Date.Created_Hir].[Created_On].[2014-03-01]
:
[Created_Date.Created_Hir].[Created_On].[2014-03-31]
MEMBER [Created_Date.Created_Hir].[All].[Set1Agg] AS
Aggregate([Set1])
MEMBER [Created_Date.Created_Hir].[All].[Set2Agg] AS
Aggregate([Set2])
MEMBER [Measures].[~Last30Days - Now] AS
(
[Created_Date.Created_Hir].[All].[Set1Agg]
,[Measures].[SomeMeasure]
)
MEMBER [Measures].[~Last60Days - Last30Days] AS
(
[Created_Date.Created_Hir].[All].[Set2Agg]
,[Measures].[SomeMeasure]
)
MEMBER [Measures].[~Measure] AS
([Measures].[~Last30Days - Now] - [Measures].[~Last60Days - Last30Days])
/
[Measures].[~Last60Days - Last30Days]
* 100
,format_string = '#,##0'
SET [~ROWS] AS
{
[Sales Order Attributes SO.Sales_order].[Sales Order ID].MEMBERS
}
SELECT
NON EMPTY
{
[Measures].[CONT_AMT_GROSS]
,[Measures].[CONT_AMT_NET]
,[Measures].[~Measure]
} ON COLUMNS
,NON EMPTY
[~ROWS] ON ROWS
FROM [SALES_ORDER]
WHERE
[~FILTER];

Where Clause using another Dimension Value

I'm trying to create a Calculated Member in my cube with where clause but couldn't figure how to achieve the proper result.
I created a calculated member "Outlook" using the below code to display only Forecast values.
CREATE MEMBER CURRENTCUBE.[Measures].[Outlook]
AS SUM(([Source Profile].[Source Profile Hierarchy].CurrentMember,
[Source Profile].[Profile Level01].&[Outlook]),
[Measures].[USD Amount]),
FORMAT_STRING = "#,##0;(#,##0)",
VISIBLE = 1 , DISPLAY_FOLDER = 'USD' , ASSOCIATED_MEASURE_GROUP = 'CARS';
Cube Result
Now I would like to filter the results dynamically based on another hidden dimension "Current_Month". This dimension always has current financial period value and it's corresponding outlook profile
Year_Month Outlook_Profile
2015010 10 + 2
Expected result should be "Outlook" measure showing value based on Current_Month dimension, which is '10 + 2' and rest of them should be 0
Expected result
Just to explain the requirement in SQL terms, I would like to achieve the below in MDX
Where Fact.Source_Profile=Dimension.Source_Profile
instead of
Where Fact.Source_Profile='10 + 2'
I'm not sure how to achieve this in Where Clause or by another means. I could see examples of hard coding values, like year.&[2015] but haven't seen one using dynamic values.
I found a solution myself and thought of sharing the same. Used StrToMember function to pass hidden dimension's member as a variable here.
CREATE MEMBER CURRENTCUBE.[Measures].[Outlook]
AS (
Sum
(
(
[Source Profile].[Source Profile Hierarchy].CurrentMember,
strtomember("[Source Profile].[Source Name].&[" + [Outlook Profile].[Outlook Profile].&[1].Member_Caption + "]")
)
,[Measures].[USD Amount]
)
),
FORMAT_STRING = "#,##0;(#,##0)",
VISIBLE = 1 , DISPLAY_FOLDER = 'USD' , ASSOCIATED_MEASURE_GROUP = 'CARS' ;

MDX Calculated member fixed

i want to ask, if there is some function in MDX language, which returns me a same value in any case..
I created a calculated member, that's indicate how much value was sold on last year. It's work fine. But if I in slicer or filter exclude year value of the last year, i get nothing. Is there any function, that calculate a value with no filter?
For example, I need function like calculate in DAX in power pivot.
Thanks
Edit:
MDX calculated member for [Mat value]:
CREATE MEMBER CURRENTCUBE.[Measures].[MAT value]
AS SUM([03 Datumy].[MAT].&[MAT],[Measures].[Sales value]),
FORMAT_STRING = "#,##0.00;-#,##0.00",
VISIBLE = 1 , DISPLAY_FOLDER = 'Sales value' , ASSOCIATED_MEASURE_GROUP = '04 Hodnoty' ;
MDX calculated member for [Mat-1 value]:
CREATE MEMBER CURRENTCUBE.[Measures].[MAT-1 value]
AS SUM([03 Datumy].[MAT].&[MAT-1],[Measures].[Sales value]),
FORMAT_STRING = "#,##0.00;-#,##0.00",
VISIBLE = 1 , DISPLAY_FOLDER = 'Sales value' , ASSOCIATED_MEASURE_GROUP = '04 Hodnoty' ;
mat2014 http://www.attanon.eu/mat2014.PNGmat2013 http://www.attanon.eu/mat2013.PNG
filters http://www.attanon.eu/filters.PNGall http://www.attanon.eu/allmat.PNG
Edit2:
MAT and MAT-1 is based on column with this value. I have dimension like this:
dimension http://www.attanon.eu/dimension.PNG
And data looks that:
datumy http://www.attanon.eu/datumy.PNG
Relationship in [03 Datumy]:
relations http://www.attanon.eu/relations.PNG
The mat is calculated in SQL server. Because, i don't have much time to calculate the hiearchy in cube.
(discussion updates were removed as lack of necessity)
UPDATE to fix an issue:
Since your calculation, that determines months belonging to certain month, based on SQL, you can filter-out Date hierarchy by rewriting MAT-measures with adding [03 Datumy].[Year].[All]:
CREATE MEMBER CURRENTCUBE.[Measures].[MAT value]
AS ([03 Datumy].[MAT].&[MAT],[03 Datumy].[Year].[All],[Measures].[Sales value]),
FORMAT_STRING = "#,##0.00;-#,##0.00",
VISIBLE = 1 , DISPLAY_FOLDER = 'Sales value' , ASSOCIATED_MEASURE_GROUP = '04 Hodnoty' ;
and the same for next one:
CREATE MEMBER CURRENTCUBE.[Measures].[MAT-1 value]
AS ([03 Datumy].[MAT].&[MAT-1],[03 Datumy].[Year].[All],[Measures].[Sales value]),
FORMAT_STRING = "#,##0.00;-#,##0.00",
VISIBLE = 1 , DISPLAY_FOLDER = 'Sales value' , ASSOCIATED_MEASURE_GROUP = '04 Hodnoty' ;
Actually, it's an equivalent of old SSAS-2000 function .Ignore.

Adding further information in the context of the cell set

I'd like to be able to search the [Employee Department] hierarchy - within any of it's levels using a string: the following does this ok and finds all members related to the string "Control"
Now I have tried to add a cross join so that I can always see the department name for each of the rows and then ORDER by the department. If the commented section is uncommented I unfortunately get a full cartesian product - I only want the departments in the context of the members found by the filter - is this possible?
WITH
MEMBER [Measures].[LevelName] AS
[Employee].[Employee Department].Level.Name
MEMBER [Measures].[LevelNumber] AS
[Employee].[Employee Department].Level.Ordinal
SET [Set_TargetEmp] AS
{
FILTER(
[Employee Department].AllMembers,
(
InStr(
1,
[Employee].[Employee Department].currentmember.name,
"Control") <> 0
)
)
}
SELECT
// ORDER(
// [Department].members,
// [Department].[Department].MEMBERVALUE
// )
// *
ORDER(
DESCENDANTS(
[Set_TargetEmp],
[Employee].[Employee Department].[Department],
SELF_BEFORE_AFTER
),
[Measures].[LevelNumber],
BASC
) as X
ON 1,
{
[Measures].[LevelName],
[Measures].[LevelNumber]
} ON 0
FROM [Adventure Works]
Assuming you use Department the Department dimension, and the Employee Department is in a different dimension named Employee, you get a cross product. Analysis Services only applies "autoexists" within the same dimension. Across dimensions, you must apply this logic explicitly like this:
ORDER(
Exists([Employee].[Department Name].[Department Name].members,
[Set_TargetEmp]
),
[Department].[Department].MEMBERVALUE
)
for the commented block in your code should deliver what you want.
In case you have more than one measure group that relate to both the department and the employee dimensions, you should state the name of the measure group to use as the third argument of Exists. This is a string argument, hence this name should be included in quotes.

Running total only covering range of cells with data

Using the illustrated mockup
(Note not all DimB members show so the total for DimA is larger than the sum of the displayed DimB, ignore this):
Query is showing (months,revenue) on 0, (dima,dimb) on 1 from cube
I would like some assistance in creating the calculated member that would calculate the running total across "Months" here (not a real time dimension).
Earlier i was using this one, but it was wrong on so many levels:
[Measures].[Accumulated Revenue] =
IIF(
([DimMonths].[Months].CurrentMember,[Measures].[Revenue]) = 0
AND ([DimMonths].[Months].CurrentMember.NextMember,[Measures].[Revenue]) = 0
,
IIF(
AGGREGATE({
[DimMonths].[Months].CurrentMember :
[DimMonths].[Months].Parent.LastChild
},[Measures].[Revenue]) = 0
,
NULL
,
Aggregate( {
[DimMonths].[Months].Parent.FirstChild :
[DimMonths].[Months].CurrentMember.PrevMember
}
,[Measures].[Revenue])
)
,
Aggregate( {
[DimMonths].[Months].Parent.FirstChild :
[DimMonths].[Months].CurrentMember
}
,[Measures].[Revenue])
)
Sounds like a job for a "scoped assignment". Basically, using a scoped assignment, you can overwrite the value of your calculated measure along the [Member_DimA_01] slice so that these values represent a running total instead of a sum of children.
Here's a good tutorial from Chris Webb on scoped assignments to help get you started...
Edit: here's a template for the running total calculation...
WITH
SET [Months] AS
{
[Date].[Calendar Month].&[2011 - Jan]
:
[Date].[Calendar Month].&[2011 - Dec]
}
MEMBER [Measures].[Running Total] AS
SUM(
{
[Date].[Calendar Hierarchy].[Calendar Month].&[2011 - Jan]
:
[Date].[Calendar Hierarchy].CurrentMember
}
,[Measures].[Revenue]
)
SELECT
NON EMPTY{
[Months]
} ON 0,
NON EMPTY{
[DimA].[Member].Allmembers *
[DimB].[Member].Allmembers
} ON 1
FROM
[<<cube name>>]
WHERE
[Measures].[Revenue Running Total]