DAX - Running Total - Multiple Critiera + Grouping - excel

I've looked everywhere for this but any other example is not exactly what I want to achieve. I have data that looks like that:
Day Group Sales
14 1 15
13 0 22
14 1 17
and so on. Now I create calculated field of Running Total using following formula:
CALCULATE (
SUM(Table[Sales]),
FILTER (
ALL (table),
Table[Date] <= MAX(Table[Date])
)
)
I create Pivot Table and put Date and Group as rows, then Running Total as Values. Why running total is not aggregated separately for each group? I would like Group 1 to have its calculation, and Group 0 too.

The reason that running total is not aggregated separately for each group is because your formula is incomplete. You have just used the ALL function for FILTER. The ALL will mean that you will ignore the existing filter contexts. So on a row with Group 0 you will ignore the Group 0 filter.
What I think you want is to retain the Group filter. You can achieve this by replacing ALL (table), with either ALLEXCEPT(table,table[Group]), or ALL(table[Date]),. Both of these will give a running total just for the Group row so you will have a running total for Group 0 and one for Group 1.
If what you are looking for is a running total where the totals accumulate by both Date and Group you can keep ALL and add an extra expression for FILTER:
CALCULATE (
SUM ( table[Sales] ),
FILTER (
ALL ( table ),
table[Date] <= MAX ( table[Date] )
&& table[Group] <= MAX ( table[Group] )
)
)

I use code bellow and it works for me
CALCULATE (
SUM ( table[Sales] ),
FILTER (
ALL ( table ),
table[Date] <= MAX ( table[Date] )
&& table[Group] = MAX ( table[Group] )
) )

Related

SUMX, SUMMARIZE, and missing values

I have a somewhat complicated scenario that I'm trying to build out in Excel using PowerPivot. We have sales pipeline items that each represent a sales opportunity and, associated with each of those pipelines, a number of events. I have history tables for both pipelines and events and would like to use them to construct a model of how a given sales executive's entire pipeline set has changed over time.
The result set from my SQL query might look like this:
pipeline_id
date_last_mod
pipeline_event_id
amount
P-01
1/1/2020
PE-01
100
P-02
1/1/2020
PE-02
500
P-02
1/2/2020
P-02
1/2/2020
PE-02
1000
P-03
1/1/2020
PE-03
200
P-03
3/1/2020
PE-03
200
P-03
4/1/2020
PE-04
300
P-03
5/1/2020
PE-03
400
P-03
5/15/2020
PE-03
300
I also have a date table with the usual fields. What I'm trying to produce is a PivotTable that looks like the following. You can see it takes the most recent 'amount' value of each pipeline event and sums those up as of the end of each month.
Year
Month
amount
2020
1
800
2020
2
800
2020
3
800
2020
4
1100
2020
5
1200
It seems like the solution should be something with SUMX and LASTNONBLANK. I have a measure that looks like this:
TestRev:=VAR MaxDate =
MAX ( qryPipelineUS[date_last_mod] )
RETURN
SUMX( ADDCOLUMNS( SUMMARIZE( qryPipelineUS, qryPipelineUS[pipeline_id], qryPipelineUS[pipeline_event_id] ), "temp",
CALCULATE (
SUM ( qryPipelineUS[amount] ),
LASTNONBLANK( qryPipelineUS[date_last_mod], CALCULATE( SUM( qryPipelineUS[amount] ) ) ),
ALL( qryDateTable ),
ALLEXCEPT( qryPipelineUS, qryPipelineUS[pipeline_event_id] ),
qryPipelineUS[date_last_mod] <= MaxDate ) ), [temp] )
The problem with it seems to be that the SUMMARIZE function won't generate rows for pipeline_event_id's in months that don't have entries for them. Makes sense, really. Even when I try to do something with CROSSJOIN, I can generate a table with the ID's I need, but can't get it to generate data.
I'd really appreciate any suggestions as to how I should go about this. I've been beating my head against the problem for a couple weeks now and I'm not getting anywhere. Thanks in advance.
The key here is to do your date calculations on the date table rather than your fact table and to remove date filters on your SUMMARIZE table.
Here's how I'd adjust your measure:
TestRev =
VAR MaxDate =
MAX ( qryDateTable[Date] )
RETURN
SUMX (
ADDCOLUMNS (
CALCULATETABLE (
SUMMARIZE (
qryPipelineUS,
qryPipelineUS[pipeline_id],
qryPipelineUS[pipeline_event_id]
),
ALL ( qryDateTable )
),
"temp",
CALCULATE (
LASTNONBLANKVALUE (
qryPipelineUS[date_last_mod],
CALCULATE ( SUM ( qryPipelineUS[amount] ) )
),
qryDateTable[Date] <= MaxDate
)
),
[temp]
)
Edit: In Excel, LASTNONBLANKVALUE is not recognized so you can use this expanded version:
Test =
VAR MaxDate = MAX ( qryDateTable[Date] )
RETURN
SUMX (
ADDCOLUMNS (
CALCULATETABLE (
SUMMARIZE (
qryPipelineUS,
qryPipelineUS[pipeline_id],
qryPipelineUS[pipeline_event_id]
),
ALL ( qryDateTable )
),
"temp",
CALCULATE (
CALCULATE (
SUM ( qryPipelineUS[amount] ),
LASTNONBLANK (
qryPipelineUS[date_last_mod],
CALCULATE ( SUM ( qryPipelineUS[amount] ) )
)
),
qryDateTable[Date] <= MaxDate
)
),
[temp]
)
Note that the date filter is not included in the same internal CALCULATE expression as LASTNONBLANK. If you did that, the measure would not work the same way.

DAX sum of multiplication (sumproduct) across multiple tables

I am struggling with what I think is a really silly problem.
I am trying to get "MTD target" values from an arbitrary date selection. I have a table 'out' which has many dimensions +date, as well as a target table which gives me a constant target value per day, for each month. My goal is to get the number of days selected per EACH month and multiply it by the corresponding daily target for the relevant month.
For example, month 1 daily target is 2, month 2 daily target is 4. I have 4 days in month 1, and 3 days in month 2. My cumulative target should be 2*4+3*2 = 14.
I can do this for a single month no problem. But as soon as I have a date range selected that crosses 2 or more months it all goes to hell.
Table 'out' has date, country, and other dimensions.
Table 'targets' has a year, month, and country dimensions.
I am trying to get some join and multiplication that is something like SUM(month_country * selected_days)
Here are the DAX measures I've tried:
mtd_inv_tgt :=
CALCULATE (
SUM ( targets[daily_spend] ),
FILTER (
targets,
targets[market] = FIRSTNONBLANK ( out[co_market], "" )
&& targets[yyyymm] >= MIN ( out[yyyymm] )
&& targets[yyyymm] <= MAX ( out[yyyymm] )
)
)
* DISTINCTCOUNT ( out[date] )
mtd_inv_tgt :=
SUMX (
FILTER (
targets,
targets[market] = FIRSTNONBLANK ( out[co_market], "" )
&& targets[yyyymm] >= MIN ( out[yyyymm] )
&& targets[yyyymm] <= MAX ( out[yyyymm] )
),
targets[daily_spend] * DISTINCTCOUNT ( out[date] )
)
This works fine if the dates selected belong to one month. If I select 2 months it will add the daily spend across 2 months and then multiply it by the number of dates covering the 2 months. Like from the above example it would be (2+3)*(4+2) = 30, which is obviously wrong.
The caveat is I can't use SUMX on the 'out' table because there are many records per date+country, whilst the targets are a single entry per month+country.
I think something similar to this should work:
mtd_inv_tgt :=
SUMX (
VALUES ( out[date] ),
LOOKUPVALUE (
targets[daily_spend],
targets[yyyymm], SELECTEDVALUE ( out[yyymm] )
)
)
This iterates over each distinct out[date] value in the current filter context and adds up the daily_spend for each of those dates that it looks up by matching on yyymm.
Iterating over only the yyymm might be more efficient:
mtd_inv_tgt :=
SUMX (
VALUES ( out[yyymm] ),
DISTINCTCOUNT ( out[date] )
* LOOKUPVALUE (
targets[daily_spend],
targets[yyyymm], EARLIER ( out[yyymm] )
)
)
Note: If these don't work as expected, please provide sample data to check against as I haven't actually tested these.

How to add an if statement in a DAX formula measure?

I am new to DAX and have created two measures to get the total pay per employee then lookup that total pay into a table and return a value in my Power Pivot.
Total Pay Measure:
NMRPaySum:=SUMX(Pay,[Regular Pay]+[Overtime Pay]+[Other Pay])
Range Lookup Measure:
SSSContributionEE :=
CALCULATE (
VALUES ( SSSContribution[EE] ),
FILTER (
SSSContribution,
[NMRPaySum] >= SSSContribution[Lower Bound] &&
[NMRPaySum] <= SSSContribution[Upper Bound]
)
)
However, I need the range lookup to only calculate if the employee type is satisfied.
The logic for it is below:
If Employee[Type]="Regular" Then
Calculate SSSConbtributionEE
Else
0
End If
I have tried this DAX formula, but doesn't seem to be working:
=
IF (
OR ( Salary[Type] = "Regular", Salary[Type] = "Agency" ),
CALCULATE (
VALUES ( SSSContribution[EE] ),
FILTER (
SSSContribution,
[NMRPaySum] >= SSSContribution[Lower Bound] &&
[NMRPaySum] <= SSSContribution[Upper Bound]
)
),
0
)
NMRPay Table:
SSS Contribution Table:
Employee Information Table:
Use your measure as is, for all the data. You then build a Pivot table, where you can use a filter or slicers on Employee Type to exclude unwanted values. Add the measure to the Values area and it will only calculate for data that is in the rows and columns of the pivot table.
For the OR condition, you should be able to add that as another filter:
= CALCULATE (
VALUES ( SSSContribution[EE] ),
FILTER (
SSSContribution,
[NMRPaySum] >= SSSContribution[Lower Bound] &&
[NMRPaySum] <= SSSContribution[Upper Bound]
),
FILTER (Salary, Salary[Type] = "Regular" || SalaryType = "Agency")
)
This may or may not work depending on your exact data model / relationship structure, but it might point you in the right direction. It's possible you need to use RELATED / RELATEDTABLE, but I'm not sure without being able to play with it myself.

DAX Moving Average Reconciliation

Following tutorials I have a dax formula that calculates a 12 month moving average. However it seems slightly off from what users would be expecting.
12 Month Moving Average:=AVERAGEX (
FILTER (
ALL (dim_Calendar ),
dim_Calendar[Month_from_date_iso] > ( NEXTDAY ( SAMEPERIODLASTYEAR ( LASTDATE (dim_Calendar[Date_iso] ) ) ) ) && /* t1 */
dim_Calendar[Month_from_date_iso] <= MAX (dim_Calendar[Date_iso] ) /* t2 */
),[Total Month Sales])
Edit: adding Total Month Sales
Total Month Sales:=CALCULATE (
SUM([Sales Gross]),
FILTER (
ALL ( dim_Calendar),
dim_Calendar[Month_from_date_iso] = MAX (dim_Calendar[Month_from_date_iso] )
)
)
I would have expected Column F to match Column E.
Am I misunderstanding how AVERAGEX works or is this a rookie error?
Edit2: progress update. Demonstrating how the proposed solution calculates the overall average, not last 12 months.

two days before Previousday dax

I have added a measure to calculate difference to yesterday's figures however
when it is Monday's figure it returns blank instead of comparing against Friday's figure.
Is there a way of asking sales figure from two days ago, I tried deducting 2 as per
previous Day Sales:=CALCULATE(
sum(Sales[1]),
PREVIOUSDAY(Calender[Date]-2))
But it didn't work
Any suggestions please?
Thanks,
B
Assuming in your context is present Sales[Date] or Calendar[Date] column you can get the previous date with sales by using a FILTER:
Previous Day Sales :=
CALCULATE (
SUM ( Sales[Sales] ),
FILTER (
ALL ( Sales ),
Sales[Date]
= CALCULATE (
MAX ( Sales[Date] ),
FILTER (
ALL ( Sales ),
COUNTROWS ( FILTER ( Sales, EARLIER ( Sales[Date] ) < Sales[Date] ) )
)
)
)
)
This is an example in Power BI, but works in Power Pivot (Excel) too.
Hope it helps.

Resources