DAX formula for - MAX of COUNT - powerpivot

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

Related

DAX Moving Average Based on 4 Level Index

I have trouble calculating MA for products' prices. Data is in the following format:
Region has municipalities, products are sold there falling into certain categories by dates on a weekly basis, and not all weeks are filled due to seasonality.
I found a ranking formula and adjusted based on these 4 criteria. Here is the DAX expression for ranking (calculated column):
index2 =
RANKX (
FILTER (
_2017,
EARLIER ( _2017[RegionName] ) = _2017[RegionName] &&
EARLIER ( _2017[MunicipalityName] ) = _2017[MunicipalityName] &&
EARLIER (_2017[ProductCategoryName] )= _2017[ProductCategoryName] &&
EARLIER ( _2017[ProductName] ) = _2017[ProductName]
),
_2017[StartDateTime],
,
ASC
)
After a change in product name, the index resets. All is good till here. But when I try to add any kind of running total according to this index, it seems to calculate prices' sum for all products, giving the same result at index reset and so on for every product.
Here are some measures I've tried:
cummulatives =
VAR ind = MAX(_2017[index2])-3
VAR m1=
CALCULATE(
SUM(_2017[SellingPrice]),
FILTER(
ALL(_2017),
_2017[index2]<=ind))
VAR m2=
CALCULATE(
COUNT(_2017[SellingPrice]),
FILTER(
ALL(_2017),
_2017[index2]<=ind))
RETURN m2
Attached is an image of the table. Any help would be much appreciated. Thanks!
If you want the cumulative sum to reset with a new ProductName, then that has to be part of your filter context. You've removed that context using the ALL() function.
You can either put it back into the filter context or else not remove it in the first place. I would suggest the latter by using ALLEXCEPT(_2017, _2017[ProductName]) instead of ALL(_2017)

If Statements For Power Pivot

I'm trying to figure out how to calculate my compliance % measures based on if statements.
If [alias]=company A, then the percentage should equal 100%. If it does not, then it should calculate the total complying spend/total overall spend.
However, when I tried to set up the if statement it gives me an error and says that the single value for "alias" column cannot be determined.
I have tried If(Values) statements, but I need it to return more than one value.
Measures always aggregate. The question is what you want the compliance calculation to be when you're looking at 2 companies? 3 companies? Right now, neither your question nor your formula accounts for this possibility at all, hence the error.
If you're thinking "Compliance % doesn't make sense if you're looking at more than one company", then you can write your formula to show BLANK() if there's more than one company:
IF (
HASONEVALUE ( 'Waste Hauling Extract'[Alias] ),
IF (
VALUES ( 'Waste Hauling Extract'[Alias] ) = "company A",
[PCT-Compliant],
[PCT Non-compliant]
),
BLANK ()
)
If you want something else to happen when there's more than one company, then DAX functions like CALCULATE, SUMX or AVERAGEX would allow you to do what you want to do.
The trick with DAX generally is that the formula has to make sense not just on individual rows of a table (where Alias has a unique value), but also on subtotals and grand totals (where Alias does not have a unique value).
Based on your comment that any inclusion of company A results in 100%, you could do something such as:
IF (
ISBLANK (
CALCULATE (
COUNTROWS ( 'Waste Hauling Extract' ),
FILTER ( 'Waste Hauling Extract', 'Waste Hauling Extract'[Alias] = "company A" )
)
),
[PCT Non-compliant],
[PCT-Compliant]
)
The new CALCULATE statement filters the Waste Hauling Extract table to just company A rows, and then counts those rows. If there are no company A rows, then after the filter it will be an empty table and the row count will be blank (rather than 0). I check for this with ISBLANK() and then display either the Non-Compliant or Compliant number accordingly.
Note: the FILTER to just company A only applies to the CALCULATE statement; it doesn't impact the PCT measures at all.

Counting items with multiple criteria

I have a table (getECRs) in PowerPivot.
Right now, I've been able to create a calculated column that counts how many times the row's customer ID (BAN) occurs in the BAN column with the following formula:
=CALCULATE(COUNTROWS(getECRs),ALLEXCEPT(getECRs,getECRs[BAN]))
What I'm having difficulty with is adding multiple criteria to the CALCULATE formula in PowerPivot.
Each row has a column that gives the date the request was generated _CreateDateKey. I'm trying to include criteria that would only include multiple BANs if they fall within 7 days (before or after) the _CreateDateKey for the row.
For example for one BAN, there are the following dates and their expected counts:
_CreateDateKey Count Explanation
6/13/2014 3 Does not include 6/23
6/13/2014 3 Does not include 6/23
6/16/2014 4 Includes all
6/23/2014 2 Does not include the 2 items from 6/13
In Excel I would use a COUNTIFS statement, like below to get the desired result (using table structure naming)
=COUNTIFS([BAN],[#BAN],[_CreateDateKey],">="&[#[_CreateDateKey]]-7,[_CreateDateKey],"<="&[#[_CreateDateKey]]+7)
But I can't seem to figure out the relative criteria needed for the dates. I tried the following as a criteria to the CALCULATE function, but it resulted in an error:
getECRs[_CreateDateKey]>=[_CreateDateKey]-7
Error: Column '_CreateDateKey' cannot be found or may not be used in this expression.
This formula answers your specific question. It's a good pattern to get down as it's highly re-usable - the EARLIER() is referencing the value of the current row (slightly more complex than this but that is the end result):
=
CALCULATE (
COUNTROWS ( getECRs ),
FILTER (
getECRs,
getECRs[BAN] = EARLIER ( getECRs[BAN] )
&& getECRs[_CreateDateKey]
>= EARLIER ( getECRs[_CreateDateKey] ) - 7
&& getECRs[_CreateDateKey]
<= EARLIER ( getECRs[_CreateDateKey] ) + 7
)
)
Fundamentally you should probably be looking to get away from the 'Excel mindset' of using a calculated column and deal with this using a measure.
An adaptation of the above would look like this - it would use the filter context of the PIVOT in which you were using it (e.g. if BAN was rows then you would get the count for that BAN).
You may need to adjust the ALL() if is too 'open' for your real world context and you might have to deal with totals using HASONEVALUE():
=
CALCULATE (
COUNTROWS ( getECRs ),
FILTER (
ALL(getECRs),
getECRs[_CreateDateKey] >= MAX ( getECRs[_CreateDateKey] ) - 7 &&
getECRs[_CreateDateKey] <= MAX ( getECRs[_CreateDateKey] ) + 7
)
)

Calculating percentile values in SSAS

I am trying to calculate percentile (for example 90th percentile point of my measure) in a cube and I think I am almost there. The problem I am facing is, I am able to return the row number of the 90th percentile, but do not know how to get my measure.
With
Member [Measures].[cnt] as
Count(NonEmpty(
-- dimensions to find percentile on (the same should be repeated again
[Calendar].[Hierarchy].members *
[Region Dim].[Region].members *
[Product Dim].[Product].members
,
-- add the measure to group
[Measures].[Profit]))
-- define percentile
Member [Measures].[Percentile] as 90
Member [Measures].[PercentileInt] as Int((([Measures].[cnt]) * [Measures].[Percentile]) / 100)
**-- this part finds the tuple from the set based on the index of the percentile point and I am using the item(index) to get the necessary info from tuple and I am unable to get the measure part
Member [Measures].[PercentileLo] as
(
Order(
NonEmpty(
[Calendar].[Hierarchy].members *
[Region Dim].[Region].members *
[Product Dim].[Product].members,
[Measures].[Profit]),
[Measures].[Profit].Value, BDESC)).Item([Measures].[PercentileInt]).Item(3)**
select
{
[Measures].[cnt],
[Measures].[Percentile],[Measures].[PercentileInt],
[Measures].[PercentileLo],
[Measures].[Profit]
}
on 0
from
[TestData]
I think there must a way to get measure of a tuple found through index of a set. Please help, let me know if you need any more information. Thanks!
You should extract the tuple at position [Measures].[PercentileInt] from your set and add the measure to it to build a tuple of four elements. Then you want to return its value as the measure PercentileLo, i. e. define
Member [Measures].[PercentileLo] as
(
[Measures].[Profit],
Order(
NonEmpty(
[Calendar].[Hierarchy].members *
[Region Dim].[Region].members *
[Product Dim].[Product].members,
[Measures].[Profit]),
[Measures].[Profit], BDESC)).Item([Measures].[PercentileInt])
)
The way you implemented it, you tried to extract the fourth (as Item() starts counting from zero) item from a tuple containing only three elements. Your ordered set only has three hierarchies.
Just another unrelated remark: I think you should avoid using complete hierarchies for [Calendar].[Hierarchy].members, [Region Dim].[Region].members, and [Product Dim].[Product].members. Your code looks like you are including all levels (including the all member) in the calculation. But I do not know the structure and names of your cube, hence I may be wrong with this.
An alternate method could be to find the median of the last 20% of the records in the table. I've used this combination of functions to find the 75th percentile. By dividing the record count by 5, you can use the TopCount function to return a set of tuples that make up 20% of the whole table sorted in descending order by your target measure. The median function should then land you at the correct 90th percentile value without having to find the record's coordinates. In my own use, I use the same measure for the last parameter in both the Median and TopCount functions.
Here's my code:
WITH MEMBER Measures.[90th Percentile] AS MEDIAN(
TOPCOUNT(
[set definition]
,Measures.[Fact Table Record Count] / 5
,Measures.[Value by which to sort the set so the first 20% of records are chosen]
)
,Measures.[Value from which the median should be determined]
)
Based on what you've supplied in your problem definition, I would expect your code to look something like this:
WITH MEMBER Measures.[90th Percentile] AS MEDIAN(
TOPCOUNT(
{
[Calendar].[Hierarchy].members *
[Region Dim].[Region].members *
[Product Dim].[Product].members
}
,Measures.[Fact Table Record Count] / 5
,[Measures].[Profit]
)
,[Measures].[Profit]
)

MDX - calculated member with unrelated dimension

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