MDX 'is not equal to' in where clause - mdx

I want to divide [Net sales] from all years by the [Year] and [Week] until now and I got problem.
I wrote two queries, but both doesn't work.
First one is basic, I just show [Net sales] divided by Weeks and Years, just how I wanted, but firstly: I'm showing weeks and years even if [Net sales] are Null, and secondly, there is 'All' member of [Year] and [Week] which isn't desired to appear.
How do I filter out the [All] and null values?
Actual query:
select
{[Measures].[Net sales]} on columns,
{([Time].[Year].MEMBERS,
[Time].[Week].MEMBERS )} on rows
from [Sales]
where (
{[Department].[Department name].&[WRO], [Department].[Department name].&[KAT]});
Second query, that doesn't work at all. This was a try to filter out [All] member of [Year].
select
{ [Measures].[Net sales] } on columns,
{ [Time].[Week].MEMBERS } on rows
from [Sales]
where ( except([Time].[Year].MEMBERS, [Time].[Year].&[All]),
{[Department].[Department name].&[WRO], [Department].[Department name].&[KAT]});
Summary: I want to present only Net Sales divided by weeks periods. Weeks should be groupped in years.

To filter out the [All] member, use CHILDREN instead of MEMBERS.
To not get Weeks and Years that have no Net Sales, use NON EMPTY:
NON EMPTY {([Time].[Year].CHILDREN,
[Time].[Week].CHILDREN )} on rows

Related

MDX - How skip 0 values in MIN agregation and how exclude some percent of results?

In my cube I have
Earnings as measure with MIN aggregation
Dimension: [Localization].[Type].&[center]
Dimension: {[Date].[Year].&[2017], [Date].[Year].&[2018]}
My query is:
What are the minimum earnings of the person who decides to buy
apartments in the city center, excluding 5% of the lowest, within
last 2 years?
Now my mdx query looks like that:
SELECT
[Measures].[MinEarnings] ON COLUMNS
FROM [cube]
WHERE
(
BottomCount ([Localization].[Type].&[center], 95, [Measures].[MinEarnings]),
{[Date].[Year].&[2017], [Date].[Year].&[2018]}
)
I have two problems:
Some earnings are 0 - how can I skip them in calculations?
If my query correctly excludes 5% of the lowest earnings?
First of all you should use toppercent not bottomcount. you want the min salary of a person who is not in last 5% not last 5. Toppercent will give you the top 95%.
Secondly to filter 0 you can use the following syntax
toppercent (
filter([Localization].[Type].&[center], [Measures].[MinEarnings]>0)
, 95, [Measures].[MinEarnings])
Even now placing the code in the where clause might not work, however try it. I would suggest that you move the toppercent to rows , then order it, then take the top1
topcount(
order(
toppercent (
filter([Localization].[Type].&[center], [Measures].[MinEarnings]>0)
,95, [Measures].[MinEarnings])
,[Measures].[MinEarnings],asc)
,1)
I have an example which gives the minum sales amount of cities, notice i have replaced nulls with 0 to make it as close as possible to your case
with member [Measures].[Internet Sales Amount2]
as
case when ([Measures].[Internet Sales Amount])=null then 0 else [Measures].[Internet Sales Amount] end
select [Measures].[Internet Sales Amount2]
on columns ,
topcount(order(toppercent(filter([Customer].[City].[City],[Measures].[Internet Sales Amount2]>0),95,[Measures].[Internet Sales Amount2]),[Measures].[Internet Sales Amount2],asc),1)
on rows
from [Adventure Works]
where [Customer].[Country].&[Canada]
in the picture below is the result before topcount 1

How to filter measure multiple times in cube

I need to product a report from my cube that looks something like the following.
(dummy data)
Where it lists sales and gross profit for today, this week, the period and year to date across the products category.
My cube is setup as follows
A date dimension
And the cube itself
Currently I have not implemented the product category pieces.
I'm struggling with how to write an MDX query that can return the sales/gross profit for a single day and then week and so on.
I can return it by itself like so
SELECT {[Measures].[Gross Profit],[Measures].[Price]} ON COLUMNS
From [Cube]
WHERE [Date].[Date Key].[2015-04-22];
and so on for the other various types (week etc), but I'm unsure as how to apply the where filter to the columnn itself rather than the overall query, or if this is even the correct way to do it and I should be making multiple MDX calls that I then compose in my app that will use this.
Can anyone give me a pointer in the right direction here?
EDIT: Seems to mostly work using the approach #Akshay Rane described however I cannot get one of my measures to work
MEMBER [This Week] as
(PeriodsToDate([Date].[Fiscal Week Date].[Fiscal Week],StrToMember('[Date].[Fiscal Week Date].[Date Key].&[' + '20140401' + ']'))
,[Measures].[Merchandise Gross Profit])
Gives me an error:
The function expects a string or numeric expression for the argument. A tuple set expression was used.
Any pointers here?
You will have to create separate Calculated Members for each time interval you want to aggregate the data upon.
This can be done in [Adventure Works] cube as follows.
WITH
MEMBER [Today] as
([Measures].[Internet Sales Amount], [Date].[Date].CURRENTMEMBER)
MEMBER [Last Week] as
AGGREGATE (
{ [Date].[Date].CURRENTMEMBER.lag(6) : [Date].[Date].CURRENTMEMBER }
, [Measures].[Internet Sales Amount]
)
SELECT
{ [Today], [Last Week] } ON 0,
{ ([Product].[Product Categories].[Category], [Date].[Date].[Date]) } ON 1
FROM
(
/*FILTERING ON SPECIFIC DATE USING SUBCUBE*/
SELECT [Date].[Date].&[20070715] ON 0
FROM [Adventure Works]
)
If you can take the different levels of date from the same user hierarchy then something like this is possible:
SELECT
{
[Date].[Calendar].[Month].&[2006]&[7]
,[Date].[Calendar].[Date].&[20050220]
}
*
{
[Measures].[Order Quantity]
,[Measures].[Internet Sales Amount]
} ON COLUMNS
,{[Product].[Category].Children} ON ROWS
FROM [Adventure Works];
The above produces results like this:

Count maximum sequel of null values - mdx query

I want to create a member based on this problem
I have a Product A being sold
I want to find the largest range of consecutive days without sale
example:
days 1,2,3 the product not sale, after that,it sold for 15 consecutive days, at 19th day it didnt sell for 2 days and after that it sold every day until the end of the month
so my maximum days without sale was 3
The following query delivers in the Microsoft sample cube Adventure Works what you want:
WITH Member Measures.[days without sales] AS
IIf( [Measures].[Internet Sales Amount] > 0
, 0
,(Measures.[days without sales], [Date].[Calendar].CurrentMember.PrevMember) + 1
)
Member Measures.[Max days without sales] AS
Max( [Date].[Calendar].[Date].Members
,Measures.[days without sales]
)
SELECT { [Measures].[Max days without sales] }
ON COLUMNS
FROM [Adventure Works]
WHERE [Product].[Product].&[486]
The measure days without sales is defined recursively, and returns how many days up to and including the current member of the [Date].[Calendar] hierarchy there was no sales. You may need to adapt the criteria for "without sale", bearing in mind that in MDX, numerical comparisons treat NULL as 0 - which is different from SQL.
This measure only works correctly if there is a member in this hierarchy for each day, i. e. there are no gaps in this hierarchy. And actually, the definition is more general than just working for days: If you use months for the [Date].[Calendar].CurrentMember, it would give you the number of months without sales, etc. It works with each level of the hierarchy.
The measure Max days without sales does not contain the product in its definition, it delivers the maximum days for whatever is in context (in this case the product in the WHERE clause).
Please note that - as actually there is a loop over all days in the [Date].[Calendar] hierarchy when calculating Measures.[Max days without sales], and within that the recursion again iterates along the previous days, and all this for each cell in the result set - this may be slow for large reports.

MDX: Limit parent aggregate by child value

My MDX is fledgling at best, and it is a realistic possibility that I don't even know how to phrase my question correctly to search for an answer. Sorry if this is a duplicate.
I have a date/time hierarchy [Dates]:
[Work Date].[Dates].[Year].[Quarter].[Month].[Day]
What I want to do is return the previous 5 years worth of data, for the month of X (let's assume January):
Year Sub Total
2008 645712.11
2009 848075.43
2010 765802.60
However, I'm having trouble restricting the "Year" data, based on the specific month. I have tried this MDX code, but it yields no results at all:
SELECT [Measures].[Sub Total] ON 0,
[Work Date].[Dates].[Year] ON 1
FROM (
SELECT [Work Date].[Dates].[Month].&[01] ON 0
FROM [Data Warehouse])
If I edit the sub-select I can get a specific year, quarter and month... but I only want to restrict the month portion and not the year. I've looked into using an EXCEPT clause, but I run into the same issue. Does that make any sense? I appreciate any help, and am not opposed to reading long articles if it will further my learning / understanding. Thanks!
After your explanation in comments: To get the same child of each hierarchy level you can use the MDX function COUSIN (here the reference on msdn). As documentation said:
Returns the child member with the same relative position under a
parent member as the specified child member.
so in your case your Date dimension has to be complete without missing months or days, so you can write a query like this (I've tested on AdventureWorks)
with member [Measures].[Sub Total]
as (Cousin([Date].[Calendar].[Month].&[2004]&[1], [Date].[Calendar].CurrentMember), [Measures].[Internet Sales Amount]) , Format_string = 'Currency'
Select {[Measures].[Internet Sales Amount],[Measures].[Sub Total] } on 0
,{
[Date].[Calendar].[Calendar Year].&[2002]
,[Date].[Calendar].[Calendar Year].&[2003]
,[Date].[Calendar].[Calendar Year].&[2004]
} on 1
from [Adventure Works]
I've put side by side the total and the sub total for the years. I am considering only these 3 years because they are complete from jan to dec and I can apply cousin operator without problem.
Hope this help!

How to groupby and filter on the same dimension in MDX

I want to create a barchart with a bar for each month and some measure.
But i also want to filter on a range of day which might not completly overlap some of the month.
When that happen I would like the aggregate count for those month to only aggregat over the days that fall in my date range not get the aggregate for the whole month.
Is that possible with MDX and if it is how should the request look like?
Create a second time dimension, using a virtual dimension of the original dimension. Use one dimension in the WHERE and another in the SELECT.
This often happens anyway if some people want 'Business Time' of quarters and periods, and others prefer months. Or if you have a financial year which runs April-April.
You can use subselect. You can find more information on this page and this page:
When a member is specified in the axis clause then that member with
its ascendants and descendants are included in the sub cube space for
the subselect; all non mentioned sibling members, in the axis or
slicer clause, and their descendants are filtered from the subspace.
This way, the space of the outer select has been limited to the
existing members in the axis clause or slicer clause, with their
ascendants and descendants as mentioned before.
Here is an example:
SELECT { [Customer].[Customer Geography].[Country].&[Australia]
, [Customer].[Customer Geography].[Country].&[United States]
} ON 1
, {[Measures].[Internet Sales Amount], [Measures].[Reseller Sales Amount]} ON 0
FROM ( SELECT {[Customer].[Customer Geography].[Country].&[Australia]
, [Customer].[State-Province].&[WA]&[US]} ON 0
FROM [Adventure Works]
)
The result will contain one row for Autralia and another one for the United States. With the subselect, I restricted the value of United Stated to the Washington state.
One way I found to do it with Mondrian is as follow
WITH MEMBER [Measures].[Units Shipped2] AS
SUM
(
{
exists([Store].[Store Country].currentmember.children,{[Store].[USA].[WA],[Store].[USA].[OR]})
},[Measures].[Units Shipped]
)
MEMBER [Measures].[Warehouse Sales2] AS
SUM
(
{
exists([Store].[Store Country].currentmember.children,{[Store].[USA].[WA],[Store].[USA].[OR]})
},[Measures].[Warehouse Sales]
)
SELECT
{[Measures].[Units Shipped2],[Measures].[Warehouse Sales2]} ON 0,
NON EMPTY [Store].[Store Country].Members on 1
FROM [Warehouse]
I am not sure if the filtering will be done in SQL like below and give good performance or be run locally
select Country, sum(unit_shipped)
where state in ('WA','OR' )
group by Country