ssas calculated member with several member properties - ssas

I'm wondering if there's any better way in writing a calculated member like this:
(
[Measures].[Number of accounts]
,[Account Status].[Account Status].&[Anonymous]
,[Account Status].[Account Status].&[Closed]
,[Account Status].[Account Status].&[Closed due to Fraud]
,[Account Status].[Account Status].&[To be closed]
,[Account Status].[Account Status].&[<unknown>]
)

This is a tuple - and a very efficient way of locating a part of the cube:
(
[Measures].[Number of accounts]
,[Account Status].[Account Status].&[Anonymous]
,[Account Status].[Account Status].&[Closed]
,[Account Status].[Account Status].&[Closed due to Fraud]
,[Account Status].[Account Status].&[To be closed]
,[Account Status].[Account Status].&[<unknown>]
)
...BUT it needs to be a specific point in the cube - but you've included several members from the same hierarchy [Account Status].[Account Status] so this is not a single point in your cube and it will therefore error.
Here is an example of a valid tuple:
WITH
MEMBER [exampleTuple] AS
(
[Measures].[Internet Sales Amount]
,[Date].[Calendar Year].&[2007]
)
SELECT
[exampleTuple] ON 0
,{
[Product].[Category].[Bikes]
,[Product].[Category].[Clothing]
} ON 1
FROM [Adventure Works];
So this gives back internet sales but only for the year 2007:
If I do what you've done and add say another member from the year hierarchy into the tuple then it gets confused as unsure which bit of the cube I'me referring to - 2006 or 2007!
WITH
MEMBER [exampleTuple] AS
(
[Measures].[Internet Sales Amount]
,[Date].[Calendar Year].&[2007]
,[Date].[Calendar Year].&[2006]
)
SELECT
[exampleTuple] ON 0
,{
[Product].[Category].[Bikes]
,[Product].[Category].[Clothing]
} ON 1
FROM [Adventure Works];
gives:
double-clicking on the word #Error tells us the exception:
Exactly the exception we'd expect.
A way around this exception is to pre-aggregate the members from the same hierarchy into a single member so the processor knows exactly which part of the cube space to go to:
WITH
MEMBER [Date].[Calendar Year].[All].[2006+2007] AS
Aggregate({[Date].[Calendar Year].&[2007],[Date].[Calendar Year].&[2006]})
MEMBER [exampleTuple] AS
(
[Measures].[Internet Sales Amount]
,[Date].[Calendar Year].[All].[2006+2007]
)
SELECT
[exampleTuple] ON 0
,{
[Product].[Category].[Bikes]
,[Product].[Category].[Clothing]
} ON 1
FROM [Adventure Works];
Now we get what we want:
We can then use this initial aggregation to do whatever we want - you mention excluding some member - this is possible:
WITH
MEMBER [Date].[Calendar Year].[All].[2006+2007] AS
Aggregate
(
Except
(
[Date].[Calendar Year].[Calendar Year].MEMBERS
,{
[Date].[Calendar Year].&[2007]
,[Date].[Calendar Year].&[2006]
}
)
)
MEMBER [exampleTuple] AS
(
[Measures].[Internet Sales Amount]
,[Date].[Calendar Year].[All].[2006+2007]
)
SELECT
[exampleTuple] ON 0
,{
[Product].[Category].[Bikes]
,[Product].[Category].[Clothing]
} ON 1
FROM [Adventure Works];

Do you mean creating a calculated measure or calculated dimension member?
Are you able to use EXCEPT or negation syntax?
Something like
(Measures.Number of accounts,Except{Status A,Status B}
or replace the word EXCept with a minus sign.

Related

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];

How to apply Hierarchize and Order by with MDX Query

I need to order Dimension with respect to descending order. without using HIERARCHIZE key word everything works fine. here i need HIERARCHIZE in order to order hierarchy level data.
Select NON EMPTY({[Measures].[Internet Sales Amount]}) dimension properties MEMBER_TYPE,CHILDREN_CARDINALITY, PARENT_UNIQUE_NAME ON COLUMNS ,NON EMPTY(HIERARCHIZE({{ORDER(drilldownlevel([Customer].[Customer Geography]),[Customer].[Customer Geography].CurrentMember.MEMBER_CAPTION,desc)}})) dimension properties MEMBER_TYPE,CHILDREN_CARDINALITY, PARENT_UNIQUE_NAME ON ROWS
Unfortunely I do not have AdvWrks cube to test the following:
SELECT
NON EMPTY
[Measures].[Internet Sales Amount] ON 0
,NON EMPTY
ORDER(
{
HIERARCHIZE([Customer].[Customer Geography].[COUNTRY].MEMBERS)
,[Customer].[Customer Geography].[COUNTRY].&[GERMANY].CHILDREN
}
,[Customer].[Customer Geography].CurrentMember.MEMBER_CAPTION
,BDESC
)
) ON 1
FROM [Adventure Works];
Looks like I had a tested solution to a similar problem here:
Issue with Order function and Crossoins in MDX
Looks like an application of the above to your context is something like this:
SELECT
NON EMPTY
[Measures].[Internet Sales Amount] ON 0
,NON EMPTY
{
Order
(
{
[Customer].[Customer Geography].[COUNTRY].MEMBERS
, [Customer].[Customer Geography].[COUNTRY].&[GERMANY].CHILDREN
}
,(
[Measures].[Internet Sales Amount]
,[Customer].[Customer Geography].[COUNTRY]
)
,BDESC
)
} ON 1
FROM [Adventure Works];
Resolved the issues with below query
SELECT
NON EMPTY [Measures].[Internet Sales Amount] ON 0,
NON EMPTY
Order(
Hierarchize(
[Customer].[Customer Geography].[Country].&[Germany].Children
)
,[Customer].[Customer Geography].CurrentMember.MEMBER_CAPTION
,DESC
)
ON 1
FROM [Adventure works];

How to use avg function in mdx?

I have my mdx query:
SELECT
NON EMPTY
{[Measures].[Amount]} ON COLUMNS
,NON EMPTY
{[Dim Date].[Day Of Week].[Day Of Week].MEMBERS} ON ROWS
FROM
(
SELECT
[Dim Date].[Date Int].&[20140730] : [Dim Date].[Date Int].&[20150730] ON COLUMNS
FROM [Cube]
WHERE
[Dim Client].[Common Client UID].&[{some id}]
);
so i have my a weekday dim, which contain members as numbers from 1-7. Query find returns amount for each weekday, which is summed up, but i want to find out an average, so somehow i need to find out how many items was summed to give me [Measures].[Amount] result. I have tryed with separate member function which didnt worked.
WITH MEMBER [Measures].[Avg] AS
Avg(
( [Dim Date].[Day Of Week].CURRENTMEMBER, [Measures].[Amount] )
)
Avg return exectly the same value. How do i do such a request in mdx?
This will give you an average over 1 member:
WITH MEMBER [Measures].[Avg] AS
Avg(
( [Dim Date].[Day Of Week].CURRENTMEMBER, [Measures].[Amount] )
)
That is because CURRENTMEMBER is returning 1 member.
If you want an average over several members than you need to supply a set as the first argument for the Avg function. Here is an example:
WITH MEMBER [Measures].[Daily Avg] AS
Avg(
Descedants(
[Date].[Date - Calendar Month].CURRENTMEMBER
,[Date].[Date - Calendar Month].[Calendar Day]
,[Measures].[Amount]
)
Although I suspect something like the follwoing should work in your context:
WITH
MEMBER [Measures].[Avg] AS
Avg
(
(EXISTING
[Dim Date].[Date Int].MEMBERS)
,[Measures].[Amount]
)
SELECT
NON EMPTY
{
[Measures].[Amount]
,[Measures].[Avg]
} ON COLUMNS
,NON EMPTY
{[Dim Date].[Day Of Week].[Day Of Week].MEMBERS} ON ROWS
FROM
(
SELECT
[Dim Date].[Date Int].&[20140730] : [Dim Date].[Date Int].&[20150730] ON COLUMNS
FROM [Cube]
WHERE
[Dim Client].[Common Client UID].&[{some id}]
);

MDX query to pivot table based on condition

I'm trying to write MDX query for pivot table.
Similar query in RDBMS is like this:
SELECT stats_Date
,ISNULL(SUM(clicks), 0) AS clicks
,ISNULL(SUM(CASE WHEN ad_type IN (1,3) THEN clicks END), 0) AS keyword_clicks
,ISNULL(SUM(CASE WHEN ad_type IN (2,3) THEN clicks END), 0) AS direct_clicks
FROM STATS_TABLE (NOLOCK)
WHERE stats_Date BETWEEN '2015-06-01' AND '2015-06-30'
GROUP BY stats_Date
I've two dimensions [DIM TIME] & [DIM AD TYPE]
I've tried below MDX query for this:
WITH
MEMBER [Measures].[Clicks Keyword] AS
IIF
(
[DIM AD TYPE].[Ad Type].CurrentMember IS [DIM AD TYPE].[Ad Type].&[1]
,[Measures].[clicks]
,0
)
SELECT {
[Measures].[Clicks]
,[Measures].[Clicks Keyword]
} ON COLUMNS
,{
[DIM TIME].[CalendarHierarchy].[Date]*[DIM AD TYPE].[Ad Type].[Ad Type]
} ON ROWS
FROM [CM_STATS_CUBE]
WHERE ([DIM TIME].[Month].&[201506]:[DIM TIME].[Month].&[201506]})
Sample output of this MDX query looks like this:
Clicks Clicks Keyword
20150501 Invalid (null) 0
20150501 unknown 200 0
20150501 Keyword 500 0
20150501 Ads 300 300
20150502 Invalid (null) 0
20150502 unknown 400 0
20150502 Keyword 600 0
20150502 Ads 500 500
but I want to only group by stats_date and the expected output is:
Clicks Clicks Keyword
20150501 1000 300
20150502 1500 500
Similar example for testing in [Adventure Works] cube database:
WITH
MEMBER [Measures].[Internet Sales Amount US] AS
IIF( [Customer].[Customer Geography].CurrentMember IS [Customer].[Customer Geography].[Country].&[United States]
,[Measures].[Internet Sales Amount]
,NULL
)
SELECT {
[Measures].[Internet Sales Amount]
,[Measures].[Internet Sales Amount US]
} ON 0
,NON EMPTY{[Date].[Calendar].[Date]} ON 1
FROM [Adventure Works]
WHERE {[Date].[Date].&[20050701]:[Date].[Date].&[20050702]}
You don't need to bother with the cross-join [DIM TIME].[CalendarHierarchy].[Date]*[DIM AD TYPE].[Ad Type].[Ad Type]
WITH
MEMBER [Measures].[Clicks Keyword] AS
IIF
(
[DIM AD TYPE].[Ad Type].CurrentMember IS [DIM AD TYPE].[Ad Type].&[1]
,[Measures].[clicks]
,0
)
SELECT
{
[Measures].[Clicks]
,[Measures].[Clicks Keyword]
} ON COLUMNS
,{[DIM TIME].[CalendarHierarchy].[Date]} ON ROWS
FROM [CM_STATS_CUBE]
WHERE
[DIM TIME].[Month].&[201506] : [DIM TIME].[Month].&[201506];
Also I would suggest using null rather than 0 in your IIF function - this should tidy up the result and speed things up:
WITH
MEMBER [Measures].[Clicks Keyword] AS
IIF
(
[DIM AD TYPE].[Ad Type].CurrentMember IS [DIM AD TYPE].[Ad Type].&[1]
,[Measures].[clicks]
,null //<<<<<<<<<<<<<<<<< better to use null rather than 0
)
SELECT
{
[Measures].[Clicks]
,[Measures].[Clicks Keyword]
} ON COLUMNS
, NON EMPTY //<<<<<<<<<<<<<<<<< now if Clicks and Clicks Keyword are both null the respective row will be excluded
{[DIM TIME].[CalendarHierarchy].[Date]} ON ROWS
FROM [CM_STATS_CUBE]
WHERE
[DIM TIME].[Month].&[201506] : [DIM TIME].[Month].&[201506];
Edit
I'd not read your script in enough detail - apologies. You can just just aggregate a set of two tuples:
WITH
MEMBER [Measures].[Clicks Keyword] AS
Sum
(
{
([DIM AD TYPE].[Ad Type].&[1],[Measures].[clicks])
,([DIM AD TYPE].[Ad Type].&[3],[Measures].[clicks])
}
)
SELECT
{
[Measures].[Clicks]
,[Measures].[Clicks Keyword]
} ON COLUMNS
, NON EMPTY //<<<<<<<<<<<<<<<<< now if Clicks and Clicks Keyword are both null the respective row will be excluded
{[DIM TIME].[CalendarHierarchy].[Date]} ON ROWS
FROM [CM_STATS_CUBE]
WHERE
[DIM TIME].[Month].&[201506] : [DIM TIME].[Month].&[201506];
The AdvWrks example you posted would just be a single tuple:
WITH
MEMBER [Measures].[Internet Sales Amount US] AS
(
[Customer].[Customer Geography].[Country].&[United States]
,[Measures].[Internet Sales Amount]
)
SELECT {
[Measures].[Internet Sales Amount]
,[Measures].[Internet Sales Amount US]
} ON 0
,NON EMPTY{[Date].[Calendar].[Date]} ON 1
FROM [Adventure Works]
WHERE {[Date].[Date].&[20050701]:[Date].[Date].&[20050702]}
If you wanted to add in Canada then there seem to be three viable alternatives:
1.
WITH
MEMBER [Measures].[Internet Sales Amount US & Canada] AS
(
[Customer].[Customer Geography].[Country].&[United States]
,[Measures].[Internet Sales Amount]
)
+
(
[Customer].[Customer Geography].[Country].&[Canada]
,[Measures].[Internet Sales Amount]
)
2.
WITH
MEMBER [Measures].[Internet Sales Amount US & Canada] AS
Aggregate
(
{
[Customer].[Customer Geography].[Country].&[United States]
,[Customer].[Customer Geography].[Country].&[Canada]
}
,[Measures].[Internet Sales Amount]
)
3.
(Switch to Sum)
WITH
MEMBER [Measures].[Internet Sales Amount US & Canada] AS
Sum
(
{
(
[Customer].[Customer Geography].[Country].&[Canada]
,[Measures].[Internet Sales Amount]
)
,(
[Customer].[Customer Geography].[Country].&[United States]
,[Measures].[Internet Sales Amount]
)
}
)
Try this:
WITH
MEMBER [Measures].[Clicks Keyword] AS
AGGREGATE({[DIM AD TYPE].[Ad Type].&[1], [DIM AD TYPE].[Ad Type].&[3]}, [Measures].[Clicks])
SELECT NON EMPTY
{
[Measures].[Clicks]
,[Measures].[Clicks Keyword]
} ON COLUMNS
, NON EMPTY
{[DIM TIME].[CalendarHierarchy].[Date]} ON ROWS
FROM [CM_STATS_CUBE]
WHERE
([DIM TIME].[Month].&[201506] : [DIM TIME].[Month].&[201506]);

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]
);