MDX subtract measures across dimensions - ssas

WITH
MEMBER CostDifference AS
Sum([Measures].[ExtendedCost]) - [Measures].[ExtendedCost]
SELECT
NON EMPTY
{
[Measures].[ExtendedCost]
,CostDifference
} ON COLUMNS
,NON EMPTY
{[Parts].[ItemDesc].MEMBERS, [Dim Date].[DateUK].MEMBERS} ON ROWS
FROM [Cube]
I'm trying to subtract a measures across different dimensions i.e. for 2 date snapshots (31/1/2010 and 28/2/2010) for all the products in DimParts
if I remove this piece of code from equation then all I get is zeros
[Dim Date].[DateUK].MEMBERS
If I use a cross join to add more than one dim even then the cost difference is zero
e.g. ,NON EMPTY
CrossJoin
(
[Parts].[ItemDesc].MEMBERS
,{[Dim Date].[DateUK]}
) ON ROWS
I'm using SQl Server 2008R2
What am I missing here.

This Sum([Measures].[ExtendedCost]) - [Measures].[ExtendedCost]
Will resolve to this
[Measures].[ExtendedCost] - [Measures].[ExtendedCost]
Which is always 0
If this Sum([Measures].[ExtendedCost]) needs to be across a complete set then you need to include that set:
Sum(
[Dim Date].[DateUK].MEMBERS
,[Measures].[ExtendedCost]
)

Related

MDX - Grand total missing when filtering

I've been working on an ExcelDNA C# xll that allows users to enter simple words (under guidance) and I construct the elaborate MDX for them to query against a remote ActivePivot cube.
During testing I've ntoticed that when filtering, the grand total disappears (presumably it's joining tuples together). How do I still get a grand total? Do I need to use SCOPE or create a calculated member?
Thanks to more advanced MDX people:
SELECT
NON EMPTY
{
[Measures].[Notional.SUM]
,[Measures].[Notional.SHORT]
,[Measures].[Notional.LONG]
} ON COLUMNS
,NON EMPTY
Hierarchize
(
Filter
(
(
[CDR].[CDR].MEMBERS
,[Book].[Book].MEMBERS
)
,
Left([Book].[Book].CurrentMember.MemberValue,2) = "22"
)
,POST
) ON ROWS
FROM [TraderCube]
WHERE
[Date].[Date].[2020-01-24];
The following is something similar against AdvWrks cube:
WITH
//>>inside the WITH clause we have moved the set
SET [FilteredSet] AS
{
Filter
(
[Reseller].[Reseller Type].[Business Type].MEMBERS
,
Left([Reseller].[Reseller Type].CurrentMember.MemberValue,2) = "sp"
OR
Left([Reseller].[Reseller Type].CurrentMember.MemberValue,2) = "VA"
)
}
//>>next we create a custom member that is the sum of the filtered set
MEMBER [Reseller].[Reseller Type].[All Visible Resellers] AS
Aggregate([FilteredSet])
SELECT
NON EMPTY
{[Measures].[Reseller Sales Amount]} ON COLUMNS
,NON EMPTY
//>> inside these curly brackets we declare a set that is the filtered set and the Total member
{
[FilteredSet]
,[Reseller].[Reseller Type].[All Visible Resellers]
} ON ROWS
FROM [Adventure Works]
WHERE
[Date].[Calendar].[Calendar Year].&[2013];
The results of the above is the following:

MDX - 3rd + dimension example needed

I am trying to learn MDX. I am an experienced SQL Developer.
I am trying to find an example of an MDX query that has more than two dimensions. Every single webpage that talks about MDX provides simple two dimensional examples link this:
select
{[Measures].[Sales Amount]} on columns,
Customer.fullname.members on rows
from [Adventure Works DW2012]
I am looking for examples that use the following aliases: PAGES (third dimension?), section (forth dimension?) and Chapter (fifth dimension?). I have tried this but I do not think it is correct:
select
{[Measures].[Sales Amount]} on columns,
Customer.fullname.members on rows,
customer.Location.[Customer Geography] as pages
from [Adventure Works DW2012]
I am trying to get this output using an MDX query (this is from AdventureWorks DW2012):
That's not a 3-dimensional resultset in your screenshot, unless there's something cropped from it.
Something like
SELECT [Geography].[Country].Members ON 0,
[Customer].[CustomerName].Members ON 1
FROM [whatever the cube is called]
WHERE [Measures].[Sales Amount]
(dimension/hierarchy/level names may not be exactly right)
would give a resultset like the one in your message.
The beyond 2nd-dimension dimensions and dimension names are not used in any client tool that I know. (Others may know different). They seem to be there in MDX so that MDX can hand >2-dimensional resultsets to clients that can handle them (e.g. an MDX subquery handing its results to the main query).
An often-used trick in MDX is to get the members of two dimensions onto one axis by cross-joining:
SELECT
{[Date].[Calendar Date].[Calendar Year].Members * [Geography].[Country].Members} ON 0,
[something else] ON 1
FROM [Cube]
How about the following - it does not send more than two dimensions back to a flat screen but it uses quite a few dimensions explicitly:
SELECT
[Measures].[Sales Amount] ON O,
[Customer].[fullname].MEMBERS ON 1
FROM
(
SELECT
[Date].[Calendar Month].[Calendar Month].&[February-2012] ON 0,
[Geography].[Country].[Country].&[Canada] ON 1,
[Product].[Product].&[Red Bike] ON 2,
[Customer].[Customer].&[foo bar] ON 3
FROM [Adventure Works DW2012]
)
I've made up the dimension | hierarchy | member combinations as I do not have access to the cube.
Also if we consider implicit dimensions then take the following:
SELECT
[Customer].[Location].[Customer Geography] ON 0,
[Customer].[fullname].[fullname].&[Aaron Flores] ON 1
FROM [Adventure Works DW2012]
WHERE
(
[Measures].[Sales Amount]
);
On the slicer I've used braces (..) which indicate a tuple, but this is actually shorthand for the following:
SELECT
[Customer].[Location].[Customer Geography] ON 0,
[Customer].[fullname].[fullname].&[Aaron Flores] ON 1
FROM [Adventure Works DW2012]
WHERE
(
[Measures].[Sales Amount]
,[Date].[Calendar Month].[Calendar Month].[All],
,[Geography].[Country].[Country].[All],
,[Product].[Product].[All]
,...
,...
....
);
The All member from every dimension in the cube could be included in this slicer without affecting the result.
So the whole nature of mdx is multi-dimensional - yes you do not get more than a 2 dimensional table returned to your screen but the way you get to that cellset could well involve many dimensions.

MDX Query - Select Columns From Same Dimensions

I have a requirement displaying data from same dimension in more than 1 column. For eg. I want to show data Year and Month wise. In my dimension structure, Year and Month belongs to same hierarchy. When I run below query I get error. PFB the query.
Select NON EMPTY {[Measures].[Target Actual Value]} ON 0,
NON EMPTY {[Realization Date].[Hierarchy].[Year Name].Members *
[Realization Date].[Hierarchy].[Month Year]} ON 1
From [Cube_BCG_OLAP]
The error I get is Query (2, 12) The Hierarchy hierarchy is used more than once in the Crossjoin function. I am new to MDX queries. Please help in this regard. Thanks in advance.
Select NON EMPTY {[Measures].[Target Actual Value]} ON 0,
NON EMPTY {[Realization Date].[Hierarchy].[Year Name].Members ,
[Realization Date].[Hierarchy].[Month Year]} ON 1
From [Cube_BCG_OLAP]
Instead of CROSSJOIN have a set as above. In a set, you can put members from same hierarchy
I like Sourav's answer - but it will put the results in one column which is slightly different than the question.
In AdvWorks this is in one column:
SELECT
[State-Province].MEMBERS ON COLUMNS
,{
[Date].[Calendar].[Calendar Year].MEMBERS
,[Date].[Calendar].[Month].MEMBERS
} ON ROWS
FROM [Adventure Works];
It is possible to switch to two columns and use a cross join but you need to find out the details of your Date dimensions Attribute hierarchies (as opposed to User hierarchies):
SELECT
[State-Province].MEMBERS ON COLUMNS
,
[Calendar Year].[All Periods].Children
* [Month].MEMBERS ON ROWS
FROM [Adventure Works];
In your cube maybe something like this:
SELECT
NON EMPTY
{[Measures].[Target Actual Value]} ON 0
,NON EMPTY
[Year Name].MEMBERS
*
[Month Year].MEMBERS ON 1
FROM [Cube_BCG_OLAP];

Getting a count of users each day in Mondrian MDX

I'm trying to write a query to give me the total number of users for each customer per day.
Here is what I have so far, which for each customer/day combination is giving the total number of user dimension entries without splitting them up by customer/day.
WITH MEMBER [Measures].[MyUserCount]
AS COUNT(Descendants([User].CurrentMember, [User].[User Name]), INCLUDEEMPTY)
SELECT
NON EMPTY CrossJoin([Date].[Date].Members, [Customer].[Customer Name].Members) ON ROWS,
{[Measures].[MyUserCount]} on COLUMNS
FROM
[Users]
The problem with your calculated member is that [User].CurrentMember is set to the All member for every row tuple, and thus the count is the total. What you need is a way for the [Customer].CurrentMember and [Date].CurrentMember to effectively filter the [User] dimension.
You need to use a measure that makes sense, i.e. that will have a non-empty value for meaningful joins of the dimension members that you're interested in.
To find this out, you could start by running a query like this:
SELECT
NON EMPTY CrossJoin(
[User].[User Name].Members,
[Measures].[Some measuse]
) ON COLUMNS,
NON EMPTY CrossJoin(
[Date].[Date].Members,
[Customer].[Customer Name].Members
) ON ROWS
FROM [Project]
You would have selected Some measure adequately. The results of that query will be a lot of empty cells, but in a given row, the columns that do have a value correspond to the Users that are related to a given Customer x Date tuple (on the row). You want to count those columns for every row. COUNT and FILTER are what you need, then the query with the calculated member will be
WITH MEMBER [Measures].[User count] AS
COUNT(
FILTER(
[User].[User Name].Members,
NOT ISEMPTY([Measures].[Some measure])
)
)
SELECT
NON EMPTY {[Measures].[User count]} ON COLUMNS,
NON EMPTY CrossJoin(
[Date].[Date].Members,
[Customer].[Customer Name].Members
) ON ROWS
FROM [Users]
I am assuming a fair bit here, but with some experimentation you should be able to work it out.

MDX - Filter multiple dimensions

I'm trying to form an MDX query such that it returns only the combinations of two dimensions where a measure meets a certain criteria. I thought this would be pretty straight forward using the FILTER function, i.e.
SELECT
NON EMPTY FILTER({[Program].[ByRegion].[Program] * [Performance Metric].[Metric].CHILDREN }, [Measures].[Point Percentage] < .95) ON ROWS,
NON EMPTY ( HIERARCHIZE([Calendar Period].[Y-Q-M].[Month of Quarter].&[3]&[1]&[2009]) , [Measures].[Point Percentage] )ON COLUMNS
FROM [QEP Revenue]
However, after running the query, it is pretty easy to see that I have a mistake because the very first result has a Point Percentage of 1.5172 which is obviously more than .95.
If I completely remove the filter:
SELECT
--NON EMPTY FILTER({[Program].[ByRegion].[Program] * [Performance Metric].[Metric].CHILDREN }, [Measures].[Point Percentage] < .95) ON ROWS,
NON EMPTY ({[Program].[ByRegion].[Program] * [Performance Metric].[Metric].CHILDREN }) ON ROWS,
NON EMPTY ( HIERARCHIZE([Calendar Period].[Y-Q-M].[Month of Quarter].&[3]&[1]&[2009]) , [Measures].[Point Percentage] )ON COLUMNS
FROM [QEP Revenue]
I get a similar result set including values above .95. Am I completely missing the point of a filter, or is there an issue with attempting to filter two dimensions at once?
I don't have your datasource, but this MDX works against the AS2000 sample cube, Foodmart (Sales cube).
SELECT
NON EMPTY
{{[Time].[Quarter].MEMBERS}} ON COLUMNS
,NON EMPTY
Filter
(
CrossJoin
(
{[Customers].[State Province].&[CA]}
,[Promotions].[All Promotions].Children
)
,
(
[Customers].[State Province].&[CA]
,[Time].&[1997].&[Q1]
,[Measures].[Unit Sales]
)
> 300
) ON ROWS
FROM [Sales]
WHERE
[Measures].[Unit Sales];
I got it cracked.
The filter was being applied correctly to the Program and Performance Metric dimensions. The issue was that the filter was applied separately from the Calendar Period dimension. So the Point Percentage of 1.5172 that showed up was allowed to show because there was a Point Percentage in another month that fulfilled the filter requirement.
I was able to rewrite the query as such to get the desired results:
SELECT
NON EMPTY
Filter
(
{
[Program].[ByRegion].[Program]*
[Performance Metric].[Metric].Children*
[Calendar Period].[Y-Q-M].[Month of Quarter].&[3]&[1]&[2009]
}
,
[Measures].[Point Percentage] < 0.95
) ON ROWS
,NON EMPTY
[Measures].[Point Percentage] ON COLUMNS
FROM [QEP Revenue];
Luckily, this query is being used in reporting services, so it is appropriate to move the Calendar Period into the ROWS. However, if I wanted to keep the Calendar Period in the COLUMNS, I wouldn't know how to solve this since the same dimension cannot be used in both axes.