MDX: how to union results from two dimensions? - mdx

I'm new to MDX. Now I want to combine two results from 2 different dimensions. I'm using codes as following:
With
MEMBER [Measures].[Student Head Count].[Program1] AS
([Program1].[Program1].&[1])
MEMBER [Measures].[Student Head Count].[Program2] AS
([Program2].[Program2].&[1])
SELECT
NON EMPTY
{
[Measures].[Student Head Count].[Program1] ,
[Measures].[Student Head Count].[Program2]
}
ON COLUMNS
FROM [Current Student Overview]
The error shows:
The Program1 calculated member cannot be created because its parent is at the lowest level in the Measures hierarchy.
I know that “Student Head Count" is at the lowest level, but I don't know how to modify the syntax. If I replace “Student Head Count" with "Test" , it's not working either. Also, "Union" does not work as I tried. Could anyone help me with modified or new MDX?
I tried with Crossjoin with following script:
SELECT
NON EMPTY
{
[Measures].[Student Head Count]
}
ON COLUMNS,
NON EMPTY
{
NONEMPTYCROSSJOIN({[Program1].[Program1].&[1]},{[Program2].[Program2] }),
NONEMPTYCROSSJOIN({[Program1].[Program1] },{[Program2].[Program2].&[1]})
}
on 1
FROM [Current Student Overview]
THe result is:
How could I eliminate or hide the "All" column in performancepoint then?

There is only one level on the Measure dimension. Your measure name should be be [Measures].[Program21] and [Measures].[Program2].
You can also rewrite your query like this:
SELECT
NON EMPTY
{
([Program1].[Program1].&[1], [Program2].[Program2].&[1])
}
ON COLUMNS
FROM [Current Student Overview]
WHERE ([Measures].[Student Head Count])
In Mdx you cannot union results from different dimensions but you can do the cross product with the CrossJoin function.
EDIT:
You do not need to use CrossJoin when you have only one member in your sets. You can do (member1, member2).
If you do not want to see All you can use a query like this one:
WITH
MEMBER [Measures].[Student Head Count Program1] AS
([Measures].[Student Head Count], [Program1].[Program1].&[1], [Program2].[Program2].[All])
MEMBER [Measures].[Student Head Count Program2] AS
([Measures].[Student Head Count], [Program1].[Program1].[All], [Program2].[Program2].&[1])
SELECT
NON EMPTY
{
[Measures].[Student Head Count Program1] ,
[Measures].[Student Head Count Program2]
}
ON COLUMNS
FROM [Current Student Overview]

Related

MDX - Grand total missing when filtering

I've been working on an ExcelDNA C# xll that allows users to enter simple words (under guidance) and I construct the elaborate MDX for them to query against a remote ActivePivot cube.
During testing I've ntoticed that when filtering, the grand total disappears (presumably it's joining tuples together). How do I still get a grand total? Do I need to use SCOPE or create a calculated member?
Thanks to more advanced MDX people:
SELECT
NON EMPTY
{
[Measures].[Notional.SUM]
,[Measures].[Notional.SHORT]
,[Measures].[Notional.LONG]
} ON COLUMNS
,NON EMPTY
Hierarchize
(
Filter
(
(
[CDR].[CDR].MEMBERS
,[Book].[Book].MEMBERS
)
,
Left([Book].[Book].CurrentMember.MemberValue,2) = "22"
)
,POST
) ON ROWS
FROM [TraderCube]
WHERE
[Date].[Date].[2020-01-24];
The following is something similar against AdvWrks cube:
WITH
//>>inside the WITH clause we have moved the set
SET [FilteredSet] AS
{
Filter
(
[Reseller].[Reseller Type].[Business Type].MEMBERS
,
Left([Reseller].[Reseller Type].CurrentMember.MemberValue,2) = "sp"
OR
Left([Reseller].[Reseller Type].CurrentMember.MemberValue,2) = "VA"
)
}
//>>next we create a custom member that is the sum of the filtered set
MEMBER [Reseller].[Reseller Type].[All Visible Resellers] AS
Aggregate([FilteredSet])
SELECT
NON EMPTY
{[Measures].[Reseller Sales Amount]} ON COLUMNS
,NON EMPTY
//>> inside these curly brackets we declare a set that is the filtered set and the Total member
{
[FilteredSet]
,[Reseller].[Reseller Type].[All Visible Resellers]
} ON ROWS
FROM [Adventure Works]
WHERE
[Date].[Calendar].[Calendar Year].&[2013];
The results of the above is the following:

Simple Calculated Member Running for Forever - MDX

I am facing very strange issue with MDX (SSAS 2014), on which simplest calculated member is taking forever to execute. Could someone please help me to understand why i am facing this issue. If i not use calculated member everything works fast and result comes in seconds. When i remove Producer attribute, query performances well.
Below is the complete query.
WITH
MEMBER Measures.AsOfDate AS ("[Policy Effective Date].[Year-Month].[Date].&[2018-01-04T00:00:00]")
MEMBER Measures.YTDPremium AS AGGREGATE (YTD(STRTOMEMBER(Measures.AsOfDate)), [Measures].[Written Premium])
SELECT NON EMPTY
{
Measures.YTDPremium
} ON COLUMNS, NON EMPTY
{
(
[Program].[Program Name].[Program Name]
,[Insuring Company].[Insuring Company Name].[Insuring Company Name]
,[Line Of Business].[Line Of Business].[Line Of Business]
,[Producer].[Producer Name].[Producer Name]
)
} ON ROWS
FROM [Premium]
Try understand what the following part does in your query
NON EMPTY { ( [Program].[Program Name].[Program Name]
,[Insuring Company].[Insuring Company Name].[Insuring Company Name]
,[Line Of Business].[Line Of Business].[Line Of Business]
,[Producer].[Producer Name].[Producer Name]
) } ON ROWS
In the above MDX you are telling the server to take a cross product of all values of "Programs", "Line Of Business" and "Producer Name". So lets say you have 4 values of programs , 3 values of line of business and 2 values of producer name. The total combinations are 4*3*2=24
Now the "Non empty" removes any combinations that are not present in your dataset. This is done by removing all rows that have "Null" value in column value.
Your measure is returning value irrespective if that combination exists or not. You can modify your Calculatedmeasure to return value only in the case if the combination is valid. This can be achived by checking an actual measure for that combination
Edit: based the below example is based on the comment
In the below example i am trying to get the internet sales amount categories and components
select
{ [Measures].[Internet Sales Amount] }
on columns,
(
[Product].[Category].[Category],
[Customer].[Country].[Country]
)
on rows
from [Adventure Works]
Result
Now add "Non empty" to the query and observe the results.
Results
Now lets add calculted measure that returns "hello". Notice how the non empty clause is ineffective.
Now modify the code make the calculated measure check other measures for null
with member measures.t as
case when [Measures].[Internet Sales Amount] = null then null else "hello" end
select
{ [Measures].[Internet Sales Amount] ,measures.t }
on columns,
non empty
(
[Product].[Category].[Category],
[Customer].[Country].[Country]
)
on rows
from [Adventure Works]
Result
The bottom line: Because of cross product your result is so huge that SSAS is having hard time handling it.

Mondrian MDX - Filter Not Applying to Multiple Members Query

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]

How filter only the children members in MDX?

When I run this mdx query, works fine (get the children members from a hierarchy level):
select {} on columns,
[Dimension].[hierarchy].[level].children on rows
from [Cube]
But, when I add some tuple on rows, doesn't filter filter the children members (shows all the members) :S
select {} on columns,
[Dimension].[hierarchy].[level].children
* [Dimension2].[hierarchy2].[level2].allmembers on rows
from [Cube]
* is a cross join - you will get the Cartesian product of [Dimension].[hierarchy].[level].children and [Dimension2].[hierarchy2].[level2].allmembers because they are different dimensions.
If they were two hierarchies from the same dimension then auto exist behaviour would limit the results e.g. Year2014 crossed with month should just show the months in 2014.
Try using DESCENDANTS function + you might not require NULLs so try the NON EMPTY
SELECT
{} ON COLUMNS,
NON EMPTY
DESCENDANTS(
[Dimension].[hierarchy].[level].[PickAHigherUpMember],
[Dimension].[hierarchy].[PickTheLevelYouWantToDrillTo]
)
*
[Dimension2].[hierarchy2].[level2].allmembers ON ROWS
FROM [Cube]
if you look at the mdx language reference for children, you will also find another example of how to use the function with a hierarchy in stead of a member_expression.
http://msdn.microsoft.com/en-us/library/ms146018.aspx
but it won't work with a hierarchy level.
Maybe the row expression was initialy a hierarchy that you've have changed into a level expression.
in the following a similar working mdx with a hierarchy on rows:
select {} on 0,
[Product].[Model Name].children
*
[Geography].[Country].[All Geographies]
on 1
FROM [Adventure Works
Philip,
I guess you want only those rows where the children have a value on the default measure. In that case you could try the following:
select {} on columns,
Nonempty([Dimension].[hierarchy].[level].children
* [Dimension2].[hierarchy2].[level2].allmembers) on rows
from [Cube]
Now if, for the children, you'd need all the members from Dimension2 then you could try:
select {} on columns,
Nonempty([Dimension].[hierarchy].[level].children, [Dimension2].[hierarchy2].[level2].allmembers)
* [Dimension2].[hierarchy2].[level2].allmembers) on rows
from [Cube]
In the second case the Nonempty function takes a second parameter and the cross join is done with the result of the Nonempty function. For the documentation on Nonempty including the usage of the second parameter see https://learn.microsoft.com/en-us/sql/mdx/nonempty-mdx

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