Using NOT IN in an MDX query - mdx

I am trying to filter out some points from a dimension in my MDX select query. I have used the Filter(, ) function as documented at http://mondrian.pentaho.com/documentation/mdx.php . The MDX being run is as follows
SELECT {[Measures].[AMOUNT]} on 0,
{Filter ([DIM1].MEMBERS, [DIM1].CurrentMember NOT IN {[DIM1].[A], [DIM1].[B], [DIM1].[C]})} on 1,
{[DIM2].[S]} on 2,
{[DIM3].[EFO]} on 3,
{[CURRENCY].[EUR]} on 4
from [CUBE]
But Measures.AMOUNT is still taking Dim1.A, Dim1.B and Dim1.C into consideration. Could you kind folks please point out what is wrong with my syntax. I have also tried the Except(,) .
Best,
Rohan
UPDATE :
Thanks to Marc , for pointing me in the right direction. I tested some more and found out that the Members function also returns a point 'All' which includes all the points on my dimension. So hence, even though the Filter() or the Except() functions were filtering the points properly, the 'All' point still contained the value for all points and hence was including them in the Measure.AMOUNT calculation. I instead used the Children function and that does not return the 'All' point so I see the desired result. Updated MDX's below
Working MDX Using Filter and NOT IN ( WARN: NOT IN is an Mondrian specific operation )
SELECT {[Measures].[AMOUNT]} on 0,
{Filter ([DIM1].Children, [DIM1].CurrentMember NOT IN {[DIM1].[A], [DIM1].[B], [DIM1].[C]})} on 1,
{[DIM2].[S]} on 2,
{[DIM3].[EFO]} on 3,
{[CURRENCY].[EUR]} on 4
from [CUBE]
Working MDX Using except
SELECT {[Measures].[AMOUNT]} on 0,
{except ( {[DIM1].Children}, {[DIM1].[A], [DIM1].[B], [DIM1].[C]} )} on 1,
{[DIM2].[S]} on 2,
{[DIM3].[EFO]} on 3,
{[CURRENCY].[EUR]} on 4
from [CUBE]
Thanks !

Instead of filter, I would use the Except function as following :
Except ([DIM1].MEMBERS, {[DIM1].[A], [DIM1].[B], [DIM1].[C]} )

I am building a custom MDX builder and I had gotten to the stage of 1..n FILTER constructs working. I tried to add EXCEPT around it and the query fired but the EXCEPT was ignored.
MDX query works but ignores the EXCEPT clause
I tried <> to, see my link/answer and it works nicely (and also means it can be chained together (working for many values I wanted ignored/filtered).

Related

MDX Query using DistinctCount, Except as a filter

I am new to MDX Querying and am trying to create a query that utilizes Except. I currently have one that works when i do a filter with a bunch of OR's but it is very slow.
What i want to do is count the distinct back order lines (where that doesn't equal 0) except when 2 aging codes are set. (050 and 060).
This query seems to work but is extremely slow (not using except)
DISTINCTCOUNT(filter([Product].[Segment - Line - Types].[Product].members,
(([Measures].[BackOrderLineCount], [Aging].[AgingCode].[Aging].&[005] ) OR
([Measures].[BackOrderLineCount], [Aging].[AgingCode].[Aging].&[010] )OR
([Measures].[BackOrderLineCount], [Aging].[AgingCode].[Aging].&[020] )OR
([Measures].[BackOrderLineCount], [Aging].[AgingCode].[Aging].&[030] )OR
([Measures].[BackOrderLineCount], [Aging].[AgingCode].[Aging].&[040] ))))
I was hoping if i switched it to "EXCEPT" it would speed it up...
Any help would be appreciated i've been searching all day for this.
You don't really need to use a FILTER function for this requirement. Also, the minus operator is as good as EXCEPT while being more handy.
You should be looking at obtaining tuples of products and aging code which have a value for back order line.
DISTINCTCOUNT([Product].[Segment - Line - Types].[Product].members *
NonEmpty(
([Aging].[AgingCode].[Aging].CHILDREN - {[Aging].[AgingCode].[Aging].&[50], [Aging].[AgingCode].[Aging].&[60]}),
[Measures].[BackOrderLineCount])
)
The NonEmpty function returns those aging codes which have back order lines.
If you had to use EXCEPT, the code would look like below:
EXCEPT
(
[Aging].[AgingCode].[Aging].CHILDREN, {[Aging].[AgingCode].[Aging].&[50], [Aging].[AgingCode].[Aging].&[60]}
)

MDX - Why Cross join between measures do not work?

In MDX, we can CROSS JOIN two members, a measure and a member but not two measures. Why is this so? What does it imply?
SELECT
[Measures].[xyz] * [DimTable1].[SomeHierarchy].[Level] on 0,
[DimTable2].[SomeOtherHierarchy].&[Value] on 1
FROM [MyCube]
// WORKS
SELECT
[Measures].[xyz] on 0,
[DimTable2].[SomeOtherHierarchy].&[Value] * [DimTable1].[SomeHierarchy].[Level] on 1
FROM [MyCube]
// OF COURSE IT WORKS
SELECT
[Measures].[xyz] * [Measures].[ABC] on 0,
[DimTable1].[SomeHierarchy].&[Value] on 1
FROM [MyCube]
// DOES NOT WORK!!
I believe you forgot:
SELECT
[dd].[hh].[mm1] * [dd].[hh].[mm2] on 0,
[DimTable1].[SomeHierarchy].&[Value] on 1 FROM [MyCube]
did not work neither. [Measures] is not different than [dd] in my example. In MDX you cannot define a tuple with _ several members _ of the _ same hierarchy _. Have a look to this gentle introduction explaining the main concepts.
EDIT
Your third query, that does not work, looks like this:
The yellow area is empty so it is understandable that it is not happy.
EDIT
Following is an analogy using Excel pivot tables which use OLAP technology
If you put a crossjoin of measures A and B on rows you get something like this:
Then if we add a very small level (with 4 members) onto columns we get the following:
So what will go into the main body of this table?
A count is possible and probably is, in MDX, if you create a custom measure (don't have a server to test this statement on). Excel will default to a count but the result is pretty pointless?

MDX Query Join Two Dimensions

I have an MDX query as follows:
WITH
MEMBER [MatCode] AS [Product].[Material]
SELECT
([MatCode]) on 0,
([Activity].[ActivityCode].[T-50051151]) ON 1
FROM
[Cube]
This returns a value such as:
MatCode
T-50051151 Null
Which tells me it is not joining the activity code to the description when I know they match up
How can I correct my MDX query to join activity code to material?
thanks
Why not try something like the following to look for areas of the cube with data? You'll can use the WHERE clause to slice by a specific measure in your cube.
SELECT
{[Activity].[ActivityCode].[T-50051151]} ON 0,
//NON EMPTY //<<include to hide nulls
{[Product].[Material].members} on 1
FROM
[Cube]
WHERE
([Measures].[someMeasure])
Your query returns the _ default _ value / cell for the tuple :
( [Activity].[ActivityCode].[T-50051151], [Product].[Material].defaultMember )
as well as the .defaultMember for every other dimension not mentionned in your query. There is nothing wrong with it.

MDX query: filter and sum of filtered

I've just started to learn MDX and i want to do a query like that:
filter data by the cost ( i've already made that query but without the sum) like that:
SELECT [Measures].[SumOfSelled] ON 0,
FILTER ([From].[From].[City].members, [Measures].[SumOfSelled]>7000) ON 1
FROM [BI-Avia]
It's working
and it is OK
BUT!!!
I need also to show the sum of filtered elements under this filtered result by cities
I know how to find it separately:
with member [Measures].FilteredSum as sum(filter([From].From].City].members,Measures].SunOfSelled]>7000),Measures].[SumOfSelled])
select{SumOfSelled} on 0
from [BI-AVIA]
But i have to show this together!! The SUM under Filtered! two in one! I need youe help! I think it's very clear for you!!!
Just define the calculated member on the [From].[From] hierarchy and then combine both queries, using a union of sets (abbreviated with + in MDX):
with member [From].[From].FilteredSum as
sum(filter([From].[From].City].members, Measures].SumOfSelled]>7000))
SELECT [Measures].[SumOfSelled]
ON 0,
FILTER ([From].[From].[City].members, [Measures].[SumOfSelled]>7000)
+
{ [From].[From].FilteredSum }
ON 1
FROM [BI-Avia]
You could possibly define the filter as a set in the WITH clause, which would avoid that Analysis Services evaluates it twice.

MDX date range query with a missing boundry date

I need an MDX query for Mondrian filtered by date, where one or both of the boundry dates may not exist. I'm using the query below that works as long as both 2013-01-01 and 2013-01-08 dimensions exist. If one of the two dates does not exist then it returns no results, even though the dimensions in between do exist. How would I get this query to work even in the case of a missing boundry date dimension?
SELECT
NON EMPTY {Hierarchize({[Measures].[Number of Something]})} ON COLUMNS,
NON EMPTY {[Date].[2013-01-01]:[Date].[2013-01-08]} ON ROWS
FROM [Users]
MDX is built with the assumption that every member that you refer to exists; it is best then to make sure all conceivable date dimension members do exist by having a separate table with these values precomputed.
You could get tricky and implement that table as a stored procedure but date dimensions don't take up a lot of space in the grand scheme of things so you'd hardly ever do this.
I don't know of any other way to solve your problem.
try to eliminate the NON EMPTY
Even I haven't yet understand the reason of implementing this logic, you can hide this by adding . If you add custom member in Mondrian try it.
/* Exclude Missing Member */
Create Set CurrentCube.[MissingMemberSet] As
iif(IsError(StrToMember("[Dimension].[Hierarchy].&[MEMBER]")),
{}, {[Dimension].[Hierarchy].&[MEMBER]});
Create Member CurrentCube.Measures.[Calculation on Missing Member]
AS
IIF ([MissingMemberSet].Count > 0,
([Dimension].[Hierarchy].&[MEMBER],Measures.[X Measure]),
0
)
,
FORMAT_STRING = "Currency",
LANGUAGE = 1033,
NON_EMPTY_BEHAVIOR = { [X Measure] },
VISIBLE = 1 , DISPLAY_FOLDER = 'Display Folder' ;
Also you can implement in using IIF(IsError or IIF(Exists MDX functions.