MDX exclude from level of hierarchy - mdx

I have a Geography hierarchy made this way:
level 1: Continent
level 2: Area
level 3: City
I have to extract data of all distinct continents, but I have to exclude a specific city from one continent.
I cannot use neither WHERE clause nor nested FROM to filter it.
I tried many solutions such as EXCEPT, FILTER and "-" functions but none worked.
Here's an example of one of my wrong attempts, which extracts data but doesn't exclude the city I don't want:
Except(
[Zone].[GeographyHierarchy].[Continent].ALLMEMBERS,
{
Descendants(
[Zone].[GeographyHierarchy].[Continent].&[ContinentIWant].&[AreaIWant].&[CityIDontWant]
, [Zone].[GeographyHierarchy].[Continent], SELF_AND_BEFORE ) }
)
Can anybody help to find a working solution?
Thank you all.
EDIT:
I think there's no solution by working on the highest level of the hierarchy, so I started filtering on the lowest level (City):
Except( [Zone].[GeographyHierarchy].[City].ALLMEMBERS,
{ [Zone].[GeographyHierarchy].[Continent].&[ContinentIWant].&[AreaIWant].&[CityIDontWant] } )
In this way I have all the distinct cities I Want, but I should now aggregate them on the higher level Continent.
Any idea on how to do it?

If you are not to use a WHERE clause then you’ll need to create a new calculated member for the continent with the exclusion
WITH
MEMBER [Zone].[GeographyHierarchy].[ALL].[ContinentIWant_exclX] AS
[Zone].[GeographyHierarchy].[Continent].&[ContinentIWant]
- [Zone].[GeographyHierarchy].[Continent].&[ContinentIWant].&[AreaIWant].&[CityIDontWant]
SET [Continents] AS
EXCEPT(
[Zone].[GeographyHierarchy].[Continent].MEMBERS,
[Zone].[GeographyHierarchy].[Continent].&[ContinentIWant]
)
+
[Zone].[GeographyHierarchy].[ALL].[ContinentIWant_exclX]
...
Not ideal but without the possibility of using the WHERE clause things become tricky

Related

MDX - CHILDREN doesn't return any values, MEMBERS do

I used the following expression in MDX:
SELECT
null ON 0,
[dim].[hier].CHILDREN ON 1
FROM [Cube]
It did not return any values. However, when I issued
SELECT
null ON 0,
[dim].[hier].[hier].MEMBERS ON 1
FROM [Cube]
It worked. What is interesting, yesterday first query was working too, so I suspect some cube change might've caused that, however I don`t have an access so I cannot check it.
Is there some subtle difference between CHILDREN and MEMBERS which causes that bahaviour? I thought the two are similar except for the fact that CHILDREN digs one level down.
Not sure about the exact semantic of CHILDREN in case you apply it to a non-member; i.e., not sure it is implemented as MEMBERS. But to reply to this sentence :
CHILDREN digs one level down
no; children returns the children of the member it is applied to. Those children does not necessarily belong to the next level down. In case of a ragged hierarchy, the children could be several levels down.
it is not working cause of this:
Do not Forget on this brackets {} >> which bounds the couple on a row (on 1)
SELECT NON EMPTY AddCalculatedMembers ( { [member name].[].[].&[]&[].children, [member name].[].[].&[1]&[].children } ) on 1, [Measures].[Sales] on 0 FROM [Cube Name];

MDX WHERE vs FILTER options

I have a query in which I need to do some filtering. I can do it in a subcube, but I am wondering if I could do this in a WHERE clause without subcube. I think this solution would be faster/cleaner. I need to filter out product models with IB>0 in last month, this is my solution so far (only part of a query):
SELECT {[Measures].[AFR],[Measures].[IB]} ON COLUMNS,
([dim_ProductModel].[ODM].children)*[Dim_Date].[Date Full].children ON ROWS
FROM
(
SELECT
FILTER([dim_ProductModel].[Product Model].children,
([Measures].[IB]*[Dim_Date].[Date Full].&[2014-04-01]>0)) ON COLUMNS FROM
[cub_dashboard_spares]
)
however, I would prefer to have it in one query without subquery something like this (its not working though):
SELECT {[Measures].[AFR],[Measures].[IB]} ON COLUMNS,
([dim_ProductModel].[ODM].children)*[Dim_Date].[Date Full].children ON ROWS
FROM
[cub_dashboard_spares]
WHERE FILTER([dim_ProductModel].[Product Model].children,
([Measures].[IB]*[Dim_Date].[Date Full].&[2014-04-01]>0))
I get some error message kind of:
he MDX function CURRENTMEMBER failed because the coordinate for the ... contains a set..
I basically understand why is he not accepting is as in an WHERE clause I should be more specific but I wonder if there is some possibility to rewrite it so that it works.
I don't want that ProductModel appears in the results set.
SELECT {[Measures].[AFR],[Measures].[IB]} ON COLUMNS,
([dim_ProductModel].[ODM].children)*[Dim_Date].[Date Full].children ON ROWS
FROM
[cub_dashboard_spares]
WHERE
({[dim_ProductModel].[Product Model].children},
[Measures].[IB],
PERIODSTODATE(
[Dim_Date].[Date Full], //<<needs to be a level from your Dim_date
[Dim_Date].[Date Full].&[2014-04-01]) //<<needs to be a member from the levelyou have used in above argument
)

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.

Aggregating MDX query results on existing facts only

I am very new to MDX, so probably I'm missing something very simple.
In my cube, I have a dimension [Asset] and a measure [Visits], calculating (in this case) how many visits an asset has been consumed by. An important thing to note is that not every visit is associated with an asset.
What I need to find out is how many visits there are that consumed at least one asset. I wrote the following query:
SELECT
[Asset].[All] ON COLUMNS,
[Measures].[Visits] ON ROWS
FROM
[Analytics]
But this query just returns the total number of visits in the cube. I tried applying the NON EMPTY modifier to both axes, but that doesn't help.
This query should give you what you expect:
WITH MEMBER [Asset].[Asset Name].[All Assets] AS
AGGREGATE( EXCEPT( [Asset].[Asset Name].MEMBERS, { [Asset].[All] } ) )
SELECT
{ [Asset].[Asset Name].[All Assets] } ON COLUMNS,
[Measures].[Visits] ON ROWS
FROM
[Analytics]
You may need to put {[Asset].[Asset Name].[All]} as second argument of Except if the All member was not excluded.
In the query I create a calculated member [Asset].[Asset Name].[all assets] that should represent all your existing assets. I supposed that your existing assets are all the members of the level [Asset].[Asset Name] but the All member.
You can find more information about the Aggregate function here.
This works as well:
SELECT
[Measures].[Visits] ON 0
FROM
[Analytics]
WHERE
DRILLDOWNLEVEL([Asset].[All])
Update: as well as this:
SELECT
[Measures].[Visits] ON 0
FROM
[Analytics]
WHERE
[Asset].[All].CHILDREN

How to get current row value in a WITH MEMBER calculation MDX?

I would like to calculate a Measure based on the current row.
Problem is I can't find a way to get the current row in a WITH MEMBER part.
WITH MEMBER [Measures].[Test] AS AVG(
NonEmptyCrossJoin(
FILTER(DESCENDANTS([Exigences].[ENVGR], [Levier], SELF),
[Exigences].CurrentMember.Name = 'Chemicals'),
DESCENDANTS([Organization].[Valeo].[Powertrain Systems], [entity], SELF)),
[Measures].[ProgressLevel])
SELECT {[Measures].[ProgressLevel], [Measures].[Test]} ON COLUMNS,
DESCENDANTS([Exigences].[ENVGR].[ENVGR-01.001], [Levier], SELF) ON
ROWS FROM [Exigences]
Chemicals is currently hard coded. That is for the example.
I would like in place of 'Chemicals' to have the current rows value.
So let's say those are the values rows will return 'Chemicals', 'Pharmacy', 'Test', I would like the [Measures].[Test] calculation to change.
Can MDX do that ? If so how can I get the current value.
I tried [Levier].CurrentMember.Name but I think it's conflicting with the [Exigences].CurrentMember.Name.
Any one has an idea ?
Thank you,
This has been taking a bit of effort but that's the advantage to have a nice gold badge. We're using the MDX Generate function and named sets (myCellSet & 2d example in link) :
Not sure this is going to work for your provider but you can try this one :
WITH MEMBER [Measures].[Test] AS AVG(
NonEmptyCrossJoin(
Generate( {[Exigences].CurrentMember} as MyCellSet,
FILTER(DESCENDANTS([Exigences].[ENVGR], [Levier], SELF),
[Exigences].CurrentMember.Name = MyCellSet.CurrentMember.Name)
)
,
DESCENDANTS([Organization].[Valeo].[Powertrain Systems], [entity], SELF)),
[Measures].[ProgressLevel])