MDX - calculated member with unrelated dimension - ssas

I have two measures:
[Measure].[ChildCount] and [Measure].[Buyings]
and two dimensions:
[Buyers] and [Sellers].
[Measure].[ChildCount] uses [Buyers] dimension to count child organization for each of the buyer.
[Measure].[Buyings] uses [Buyers] and [Sellers] to count buying from [Seller] to [Buyer].
What I want to achieve is select all buyings for Buyers with ChildCount < 1 and Buyers with ChildCount > 0.
Currently these queries are working fine:
First one that count buying for each sender/buyer:
SELECT [Measure].[Buyings] on COLUMNS,
[Sellers].[Code].[Code] *
[Buyers].[Code].[Code] ON ROWS
FROM MyCube
And second that calculates buyings for buyers with and without childs:
WITH MEMBER [Measure].[BuyingsWithChilds]
as SUM
(
FILTER([Buyers].[Code].[Code],[Measure].[ChildCount]>0),
[Measure].[Buyings]
)
MEMBER [Measure].[BuyingsWithoutChilds]
as SUM
(
FILTER([Buyers].[Code].[Code],[Measure].[ChildCount]<1),
[Measure].[Buyings]
)
SELECT
{
[Measure].[BuyingsWithChilds],
[Measure].[BuyingsWithoutChilds]
} ON COLUMNS,
[Buyers].[Code].[Code] ON ROWS
FROM MyCube
But if I trying to combine these queries into desired one:
WITH MEMBER [Measure].[BuyingsWithChilds]
as SUM
(
FILTER([Buyers].[Code].[Code],[Measure].[ChildCount]>0),
[Measure].[Buyings]
)
MEMBER [Measure].[BuyingsWithoutChilds]
as SUM
(
FILTER([Buyers].[Code].[Code],[Measure].[ChildCount]<1),
[Measure].[Buyings]
)
SELECT
{
[Measure].[BuyingsWithChilds],
[Measure].[BuyingsWithoutChilds]
} ON COLUMNS,
[Sellers].[Code].[Code] ON ROWS
FROM MyCube
This query's execution takes forever.
Is it possible to fix or optimize this?

If you convert [Measure].[ChildCount]>0 and [Measure].[ChildCount]<1 to an attribute like "HasChildren", then you can avoid the Filter function which is normally slow, and which you use two times.
Then your WITH clause would be simplified to
WITH MEMBER [Measure].[BuyingsWithChilds]
as ([Buyers].[HasChildren].[Yes], [Measure].[Buyings])
MEMBER [Measure].[BuyingsWithoutChilds]
as ([Buyers].[HasChildren].[No], [Measure].[Buyings])
which should be much faster, as it uses the standard aggregation of [Measure].[Buyings].

Related

MDX aggregate out a dimension

I'm trying to compute outcome frequencies, i.e., count divided by total.
I can't work out how to get a total in MDX.
Data looks like this.
The fact is just a 1 so their sum is the number of experiments with the given outcome.
It's easy in SQL
SELECT Session, Outcome, fi / N AS p
FROM (
SELECT Session, Outcome, CAST(COUNT(*) AS float) AS fi, CAST(SUM(COUNT(*)) OVER (PARTITION BY Session) AS float) AS N GROUP BY Session, Outcome
) T
Is it possible in MDX? If so: how?
I've tried these:
CREATE MEMBER CURRENTCUBE.Measures.Experiments AS SUM([Outcomes] , Measures.[Actual Outcome]);
CREATE MEMBER CURRENTCUBE.Measures.ExperimentsA AS SUM([Outcomes].[(All)] , Measures.[Actual Outcome]);
CREATE MEMBER CURRENTCUBE.Measures.ExperimentsAM AS SUM([Outcomes].AllMembers , Measures.[Actual Outcome]);
The first and third just give (null) and the second is just the same as the existing measure -- which makes no sense.
CREATE MEMBER CURRENTCUBE.[Measures].[Experiments]
AS
SUM([Outcomes].[All], [Measures].[Actual Outcomes])
;
So: what is the difference between [All] and [(All)]?

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]

DAX formula for - MAX of COUNT

I have the below dataset:
using the measure:
BalanceCount := COUNT(Balances[Balance])
which gives me the result:
However, I want the Grand Total to show the maximum amount of the BalanceCount, which is 2.
NewMeasure:=
MAXX(
SUMMARIZE(
FactTable
,FactTable[Account]
,FactTable[MonthEnd]
)
,[BalanceCount]
)
SUMMARIZE() groups by the columns specified, and MAXX() iterates through the table specified, returning the maximum of the expression in the second argument evaluated for each row in its input table.
Since the filter context will limit the rows of the fact table, we'll only have the appropriate subsets in each column/row grand total.
I found a solution that works for this particular case. It will not work if columns other than Account and MonthEnd are included in the filter context.
MaxBalanceCount:=
MAXX ( SUMMARIZE (
Balances,
Balances[Account],
Balances[MonthEnd]
),
CALCULATE ( COUNTROWS ( Balances ) )
)

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

Filtering dimensions in MDX inside a SUM

I am new to MDX expressions and I am trying to create one that sums the value of a given measure filtered by dimensions.
In my database I have several different dimensions that have the same name: "Answer". To sum them up, I have created the query below:
WITH MEMBER Measures.Total as SUM ({[Activity].[Activity].&[14], [Activity][Activity].&[22]},
[Measures].[Activity time])
SELECT NON EMPTY [Measures].[Total] on COLUMNS from [My Analytics]
This query works, however I had to use the "&[14]" and "&[22]" statments that correspond to two different "Answer" dimensions.
Since I have more than two dimensions with the same name, is there a way to rewrite the query above in a way that I would select all these dimensions without having to add their unique ID? For example, I would re-write the query as something like this:
WITH MEMBER Measures.Total as SUM ({[Activity].[Activity].&["Answer"]},
[Measures].[Activity time])
SELECT NON EMPTY [Measures].[Total] on COLUMNS from [My Analytics]
Is this possible?
Thanks!
You can use the Filter function as following:
with
set [my-answers] as
Filter( [Activity].[Activity].members,
[Activity].[Activity].currentMember.name = 'Answer'
)
member [Measures].[Total] as Sum( [my-answers] )
...