Sum of Previous months Sales with MDX - mdx

The below query works okay.
With Member PyMonthSales as
SUM(PARALLELPERIOD([Date].[Calendar].[Month], 1),[Measures].[Internet Sales Amount])
select
{PyMonthSales} on Columns,
[Date].[Calendar].[Month] on Rows
FROM
(
Select {
[Date].[Calendar].[Month].&[2006]&[5], [Date].[Calendar].[Month].&[2006]&[4]
} on Columns
From [Adventure Works]
)
But I just want one Grand total. So I removed the rows, on the above query
With Member PyMonthSales as
SUM(PARALLELPERIOD([Date].[Calendar].[Month], 1),[Measures].[Internet Sales Amount])
select
{PyMonthSales} on Columns
FROM
(
Select {
[Date].[Calendar].[Month].&[2006]&[5], [Date].[Calendar].[Month].&[2006]&[4]
} on Columns
From [Adventure Works]
)
This is where the problem starts. Returns null. Any assistance would be great.
Thanks for your time.
Naz

It ended up a bit messy!!
WITH
MEMBER [Measures].x AS
Aggregate
(
Generate
(
{
[Date].[Calendar].[Month].&[2006]&[5]
,[Date].[Calendar].[Month].&[2006]&[4]
}
,{
ParallelPeriod
(
[Date].[Calendar].[Month]
,1
,[Date].[Calendar].CurrentMember
)
}
)
,[Measures].[Internet Sales Amount]
)
SELECT
x ON 0
FROM [Adventure Works];
The thing I kept forgetting was the curly brackets around the ParallelPeriod section - without those an exception is raised because Generate always wants a SET as its second argument.

Related

I'm stuck with MDX query

i need sales amount of first month of each quarter
WITH SET [FIRSTMONTHOFQTR] AS
DESCENDANTS(
DESCENDANTS(
[Date].[Calendar].CURRENTMEMBER,
[Date].[Calendar].[Calendar Quarter]
),
[Date].[Calendar].[Month]
)
SELECT {
[Measures].[Sales Amount]
} ON COLUMNS,
{
[FIRSTMONTHOFQTR]
} ON ROWS
FROM [Adventure Works];
With above im getting each month but i need only first month. how can i filter that?
This is one approach:
WITH
SET [Qtrs] AS
[Date].[Calendar].[Calendar Quarter]
SET [FIRSTMONTHOFQTR] AS
Generate
(
[Qtrs] AS s
,Head(Descendants(s.CurrentMember,[Date].[Calendar].[Month]))
)
SELECT
{[Measures].[Sales Amount]} ON COLUMNS
,[FIRSTMONTHOFQTR] ON ROWS
FROM [Adventure Works];
It returns the following:

MDX query for bottomcount function

SELECT
[Measures].[Internet Sales Amount] ON COLUMNS
,BottomCount
(
NonEmpty([Customer].[Customer].[Customer].MEMBERS)
,10
,[Measures].[Internet Sales Amount]
) ON ROWS
FROM [Adventure Works]
WHERE
[Date].[Calendar].[Calendar Year].&[2005];
The above query is showing me result having last 10 customer names with NULL measure value. I am using Adventure works Cube.
As per my understanding "bottomcount" is not working fine with where clause in "mdx" query. I want to fetch last 10 customer names for 2005 with measure value and hopefully i am looking for solution without using keyword "DESCENDANTS".
Please let me know in case, I am doing something wrong.
Give this a try:
bottomcount(
nonempty(
[Customer].[Customer].[Customer].Members
,[Measures].[Internet Sales Amount]
)
,10
,[Measures].[Internet Sales Amount]
)
You were getting the Customer names with NULL because in OLAP you are doing the cartesian product between the 2 dimensions (Measures is a special dimension, but it still acts as a dimension) it does not matter that you don't have values it will still crossjoin the members in your 2 sets and unless you request just the nonempty ones it will still give you the NULLs.
And if you'd like their full internet sales amount then move some of the logic into the WITH clause:
WITH
SET bot AS
NonEmpty
(
[Customer].[Customer].[Customer].MEMBERS
,(
[Measures].[Internet Sales Amount]
,[Date].[Calendar].[Calendar Year].&[2005]
)
)
SELECT
[Measures].[Internet Sales Amount] ON COLUMNS
,BottomCount
(
bot
,10
,[Measures].[Internet Sales Amount]
) ON ROWS
FROM [Adventure Works];

Creating a measure by filtering out a set from an existing measure

I am trying to implement something as follows:
WITH MEMBER Measures.Test2 AS
Sum
(
{
[Date].[Calendar].[Calendar Year].&[2006]
,[Date].[Calendar].[Calendar Year].&[2007]
}
,[Measures].[Internet Sales Amount]
)
SELECT Measures.Test2 ON COLUMNS
FROM [Adventure Works];
But i want the new measure Test2 to be sliceable according to the Calendar Year dimension. So i want something like
SELECT {Measures.Test2} ON 0,
{[Date].[Calendar].[Calendar Year].[Calendar Year].MEMBERS} ON 1
FROM [Adventure Works];
This is giving the same value for both the years 2006 and 2007.
In essence i want to create a member by taking a subset of an existing measure and then using it for further calculations
This script is not valid mdx:
SELECT (Measures.Test2,[Date].[Calendar].[Calendar Year].[Calendar Year] ON COLUMNS
FROM [Adventure Works];
You have a single ( before Measures.
Also you look like you're about to add a tuple ON COLUMNS which is not allowed. Only sets are allowed on rows and columns:
SELECT
{Measures.Test2} ON 0,
{[Date].[Calendar].[Calendar Year].[Calendar Year].MEMBERS} ON 1
FROM [Adventure Works];
Try the following:
WITH
MEMBER Measures.Test2 AS
Sum
(
Intersect
(
{[Date].[Calendar].CurrentMember}
,{
[Date].[Calendar].[Calendar Year].&[2006]
,[Date].[Calendar].[Calendar Year].&[2007]
}
)
,[Measures].[Internet Sales Amount]
)
SELECT
[Measures].test2 ON COLUMNS
,{[Date].[Calendar].[Calendar Year].MEMBERS} ON ROWS
FROM [Adventure Works];
The above returns this:
Or maybe all you want is a subselect:
SELECT
[Measures].[Internet Sales Amount] ON COLUMNS
,{[Date].[Calendar].[Calendar Year].MEMBERS} ON ROWS
FROM
(
SELECT
{
[Date].[Calendar].[Calendar Year].&[2006]
,[Date].[Calendar].[Calendar Year].&[2007]
} ON 0
FROM [Adventure Works]
);

How to count YTD days in my MDX query

I've below MDX query which gives me YTD amount for each my device perfectly, but I want count of those YTD days taken in consideration while calculating YTD amount.
How can I achieve those YTD days counts in my query?
WITH
MEMBER [Settlement Date].[Calendar].[CalendarYTD] AS
Aggregate
(
YTD
(
[Settlement Date].[Calendar].[Settlement Calendar Month].&[201412]
)
)
SELECT
[Settlement Date].[Calendar].[CalendarYTD] ON COLUMNS
,NON EMPTY
[Device].[DeviceID].Children ON ROWS
FROM [cube1]
WHERE
[Measures].[amount];
OR
you can use below AW MDX query while making changes which give same results as my above query:
WITH
MEMBER [Date].[Calendar].[CalendarYTD] AS
Aggregate(YTD([Date].[Calendar].[Month].[March 2015]))
SELECT
[Date].[Calendar].[CalendarYTD] ON COLUMNS
,[Product].[Category].Children ON ROWS
FROM [Adventure Works]
WHERE
[Measures].[Order Quantity];
this is a little swapped around but hopefully heading in the direction you require:
WITH
MEMBER [Date].[Calendar].[CalendarYTD] AS
Aggregate(YTD([Date].[Calendar].[Month].[March 2007]))
MEMBER [Measures].[DaysCompleteCurrYear] AS
Descendants
(
YTD([Date].[Calendar].[Month].[March 2007])
,[Date].[Calendar].[Date]
,SELF
).Count
SELECT
{
[Measures].[DaysCompleteCurrYear]
,[Measures].[Order Quantity]
} ON COLUMNS
,[Product].[Category].Children ON ROWS
FROM [Adventure Works]
WHERE
[Date].[Calendar].[CalendarYTD];
If we put the target month into a single member set then the family relationships are preserved and we can use that set in the custom measures:
WITH
SET [targMth] AS
{[Date].[Calendar].[Month].[March 2007]}
MEMBER [Date].[Calendar].[CalendarYTD] AS
Aggregate(YTD([targMth].Item(0).Item(0)))
MEMBER [Measures].[DaysCompleteCurrYear] AS
Descendants
(
YTD([targMth].Item(0).Item(0))
,[Date].[Calendar].[Date]
,SELF
).Count
SELECT
{
[Measures].[DaysCompleteCurrYear]
,[Measures].[Order Quantity]
} ON COLUMNS
,[Product].[Category].Children ON ROWS
FROM [Adventure Works]
WHERE
[Date].[Calendar].[CalendarYTD];

Elegant way to ignore null when applying RANK

This article gives a method for ignoring null when applying RANK : http://www.bidn.com/blogs/CraigLove/ssas/2617/mdx-walkthrough
Is there a more elegant way of doing this than using CASE ?
WITH
MEMBER [Measures].[City Rank]
AS
CASE
WHEN
NOT ISEMPTY
(
(
[Geography].[City].CurrentMember
,[Measures].[Reseller Sales Amount]
)
)
THEN
RANK
(
[Geography].[City].CurrentMember
,[Geography].[City].AllMembers
,[Measures].[Reseller Sales Amount]
)
ELSE
NULL
END
SET [OrderedCity]
AS
ORDER
(
[Geography].[City].AllMembers
,[Measures].[Reseller Sales Amount]
,DESC
)
SELECT
{
[Measures].[City Rank]
,[Measures].[Reseller Sales Amount]
} ON COLUMNS
,NON EMPTY [OrderedCity] ON ROWS
FROM [Adventure Works];
You could apply the NonEmpty function within OrderedCity:
WITH
SET [OrderedCity]
AS
NonEmpty(
ORDER
(
[Geography].[City].AllMembers
,[Measures].[Reseller Sales Amount]
,DESC
)
)
MEMBER [Measures].[City Rank]
AS
RANK
(
[Geography].[City].CurrentMember
,[OrderedCity]
)
SELECT
{
[Measures].[City Rank]
,[Measures].[Reseller Sales Amount]
} ON COLUMNS
,[OrderedCity]
ON ROWS
FROM [Adventure Works];
This way the NON EMPTY is applied on the set on the rows before it it put there, so there is no need to apply it on the rows themselves. Furthermore, re-using the set within the definition of City Rank allows Analysis Services to calculate the sorting only once, and cache the ordered set. Otherwise, the Rank would require the ordering to be re- calculated for each row.