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.
Related
We currently have a query that shows the value of total quantity, or sales across store locations and departments, I intersect the quantity sold aggregated measure against locations, and the results are fine.
When we try to filter by total qty > 500, I am only seeing the sum of quantity evaluated by the location's value, not grouped by location and department.
HAVING is not seemingly supported, and if I include a where filter at the bottom, there is an issue with the same family/members being used multiple times and it's not allowed.
SELECT
{HEAD([dim_productfamily.hier_productfamily].[lvl_department].Members, 5)}
ON ROWS,
FILTER
(
{HEAD([dim_locations.hier_locations].[lvl_location].Members, 5) * [Measures].[total_qty]},
[Measures].[total_qty] > 500
)
ON COLUMNS
FROM
[sales_daily]
WHERE
{[dim_date.hier_date].[lvl_date].[20170521] : [dim_date.hier_date].[lvl_date].[20170730] }
The above query returns fine, but I get values that I've tested only really compare against the location sum(total_qty).
EDIT for Different Grouping
I tried using the below query, which seems to work. I think the way we render a table is improper in this case, as the output does seem to work fine.
SELECT
FILTER
(
{HEAD([dim_productfamily.hier_productfamily].[lvl_department].Members, 5) * HEAD([dim_locations.hier_locations].[lvl_location].Members, 5)},
[Measures].[total_qty] > 26
)
ON ROWS,
[Measures].[total_qty]
ON COLUMNS
FROM
[sales_daily]
WHERE
{[dim_date.hier_date].[lvl_date].[20170521] : [dim_date.hier_date].[lvl_date].[20170730] }
Is this what you were thinking?
The issue is that in your filter you really have not grouped by location and department. You have only grouped by location. An easy fix is the you bring both location and product on the same axis and that the measure on the oposite axis. Then filter it. It would work.
Looking at the problem again, you can query it in the below manner. This will let you use the orignal grouping.
WITH
MEMBER [Measures].[Data Type3] AS ([Geography].[Country].CurrentMember,[Product].[Product].CurrentMember,[Measures].[Reseller Sales Amount])
SELECT
FILTER
(
{[Product].[Product].Members}
,[Measures].[Reseller Sales Amount] > 2000
)
ON rows,
FILTER
(
([Geography].[Country].members, {[Measures].[Reseller Sales Amount]
,[Measures].[Data Type3]}),
[Measures].[Reseller Sales Amount] > 2000
)
ON columns
FROM
[Adventure Works]
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]
)
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];
In my time dimensions i have 2013,2014,2015.
How can i make a Union in this mdx so i get the results from this mdx for all thoose years and not only for 2014 like in the example..
select NON EMPTY {[Measures].[Absatz Plan], [Measures].[Umsatz Plan], [Measures].[Absatz Effektiv], [Measures].[Umsatz Effektiv]} ON COLUMNS,
NON EMPTY Crossjoin(Hierarchize({([Time].[2014], [Artikel].[All Artikels], [Markt].[All Markts])}), {[Version].[14], [Version].[16], [Version].[18]}) ON ROWS
from [Budget]
Just apply CrossJoin twice:
select NON EMPTY
{[Measures].[Absatz Plan], [Measures].[Umsatz Plan], [Measures].[Absatz Effektiv], [Measures].[Umsatz Effektiv]}
ON COLUMNS,
NON EMPTY
CrossJoin(
Crossjoin(
{[Time].[2013], [Time].[2014], [Time].[2015]},
{([Artikel].[All Artikels], [Markt].[All Markts])}
),
{[Version].[14], [Version].[16], [Version].[18]}
)
ON ROWS
from [Budget]
I removed the Hierarchize, as I think it is not necessary in this context. It would order its argument by the order defined for the hierarchy in the cube. If the order of the result seems wrong, you could re-add it.
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.