MDX query: filter and sum of filtered - sql

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.

Related

MDX Result Count

I am a beginner in MDX queries. Can any one tell me how to get the record count that is a result of a MDX query?
The query is following:
select {[Measures].[Employee Department History Count],[Measures].[Rate]} on columns, Non Empty{{Filter([Shift].[Shift ID].[Shift ID].Members, ([Shift].[Shift ID].CurrentMember.name <> "1"))}*{[Employee].[Business Entity ID].[Business Entity ID].Members}} on rows from [Adventure Works2012].
I have tried various methods and I haven't really got a solution for that.
I assume you mean row count when you talk of "record count", as MDX does not know a concept of records, but the result shown from an MDX query is the space built by the tuples on the axes.
I see two possibilities to get the row count:
Just count the rows returned from your above query in the tool from which you call the MDX query.
If you want to count in MDX, then let's state what you want to have:
You want to know the number of members of the set of non empty combinations of [Shift ID]s and [Business Entity ID]s where the Shift ID is not "1" and at least one of the measures [Employee Department History Count] and [Rate] is not null.
To state that different: Let's call the tuples like above for which the first measure is not null "SET1", and the tuples like above for which teh second measure is not null "SET2". Then you you want to know the count of the the tuples which are contained in one of these sets (or in both).
To achieve this, we define these two sets and then a calculated menber (a new measure in our case) containing this calculation in its definition, and then use this calculated member in the select clause to show it:
WITH
SET SET1 AS
NonEmpty({{Filter([Shift].[Shift ID].[Shift ID].Members,
([Shift].[Shift ID].CurrentMember.name <> "1"))}
* {[Employee].[Business Entity ID].[Business Entity ID].Members}},
{[Measures].[Employee Department History Count])
SET SET2 AS
NonEmpty({{Filter([Shift].[Shift ID].[Shift ID].Members,
([Shift].[Shift ID].CurrentMember.name <> "1"))}
* {[Employee].[Business Entity ID].[Business Entity ID].Members}},
{[Measures].[Rate])
MEMBER [Measures].[MyCalculation] AS
COUNT(SET1 + SET 2)
SELECT [Measures].[MyCalculation] ON COLUMNS
FROM [Adventure Works2012]
Please note:
The sets SET1 and SET2 are not absolutely necessary, you could also put the whole calculation in one long and complicated definition of the MyCalculation measure, but splitting it up makes is easier to read. However, the definition of a new member is necessary, as in MDX you can only put members on axes (rows, columns, ...). These members can either already been defined in the cube, or you have to define them in the WITH clause of your query. There is no such thing as putting expressions/calculations on axes in MDX, only members.
The + for sets is a union which removes duplicates, hence this operation gives us the tuples which have an non empty value for at least one of the measures. Alternatively, you could have used the Union function equivalently to the +.
The Nonempty() I used in the definitions of the sets is the NonEmpty function, which is slightly different from the NON EMPTY keyword that you can use on the axes. We use one of the measures as second argument to this function in both set definitions.
I have currently no working SSAS installation available to test my statement, hence there might be a minor error or typo in my above statement, but the idea should work.

How to filter columns via MDX

Im new (couple of days to be exact) on Cubes, I have the following problem.
I have a Measure that brings certain amount of data, 100 rows for example. From that data I want to filter numbers that are < 0 from one of its columns.
For example this measure:
[Measures].[Distribution CSU Groups]
Will bring data like this
enter image description here
As you can see in the link, I want to filter those rows that have negative values on the 3rd column.
Is it possible to do this via MDX and how?
Yes filtering is possible in mdx via the following functions:
IIF function
FILTER function
HAVING clause

How to use aggregate function to filter a dataset in ssrs 2008

I have a matrix in ssrs2008 like below:
GroupName Zone CompletedVolume
Cancer 1 7
Tunnel 1 10
Surgery 1 64
ComplatedVolume value is coming by a specific expression <<expr>>, which is equal to: [Max(CVolume)]
This matrix is filled by a stored procedure that I am not supposed to change if possible. What I need to do is that not to show the data whose CompletedVolume is <= 50. I tried to go to tablix properties and add a filter like [Max(Q9Volume)] >= 50, but when I try to run the report it says that aggregate functions cannot be used in dataset filters or data region filters. How can I fix this as easy as possible?
Note that adding a where clause in sql query would not solve this issue since there are many other tables use the same SP and they need the data where CompletedVolume <= 50. Any help would be appreciated.
EDIT: I am trying to have the max(Q9Volume) value on SP, but something happening I have never seen before. The query is like:
Select r.* from (select * from results1 union select * from results2) r
left outer join procedures p on r.pid = p.id
The interesting this is there are some columns I see that does not included by neither results1/results2 nor procedures tables when I run the query. For example, there is no column like Q9Volume in the tables (result1, result2 and procedures), however when I run the query I see the columns on the output! How is that possible?
You can set the Row hidden property to True when [Max(CVolume)] is less or equal than 50.
Select the row and go to Row Visibility
Select Show or Hide based on an expression option and use this expression:
=IIF(
Max(Fields!Q9Volume.Value)<=50,
True,False
)
It will show something like this:
Note maximum value for Cancer and Tunnel are 7 and 10 respectively, so
they will be hidden if you apply the above expression.
Let me know if this helps.

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 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.