Prev years YTD sales Dax formula - powerbi

I am having some difficulties in creating a dax formula for calculating prev yr YTD sales.
I have written a formula but the same is not working.
I need to calculate the performance % yr over yr by comparing YTD sales of current year to YTD of prev yr sales.
any help would be appreciated
Sales sameperiod =
VAR first_date =
FIRSTDATE ( DATEADD ( 'Date'[Date], -12, MONTH ) )
VAR last_date =
LASTDATE ( DATEADD ( 'COGS Data'[Invoice Date], -12, MONTH ) )
RETURN
IF (
ISBLANK ( first_date ) || ISBLANK ( last_date ),
BLANK (),
CALCULATE (
SUM ( 'COGS Data'[Final Unit Cost] ),
DATESBETWEEN ( 'Date'[Date], first_date, last_date )
)
)

there are multiple ways, but my go-to is creating a Date table, I assume you already have it.
Then you would create relationship to Fact table from DateKey, and a new matrix visual with rows from Date Table, for example Date and Month. And Measure would be like -
Revenue last year = IF(
HASONEVALUE ('Date'[Month]),
IF (
SUM ('COGS Data'[Final Unit Cost] ) <> BLANK(),
CALCULATE (
SUM ( 'COGS Data'[Final Unit Cost] ),
SAMEPERIODLASTYEAR ('Date'[Date])
)
),
CALCULATE (
SUM ( 'COGS Data'[Final Unit Cost] ),
DATESBETWEEN (
'Date'[Date],
EDATE ( MIN ('Date'[Date]), -12 ),
EDATE ( MAX ('COGS Data'[Invoice Date]), -12 )
)

Related

Rank non-contiguous dates with a monthly reset

With reference to the below sample data, I have a table in Power BI that currently only contains the Bus_Day column. I am attempting to add the MTD column (in red) that counts the monthly cumulative number of Bus_Day. The rows highlighted in yellow are reflective of the requirement that the MTD Day column should reset to 1 for the first Bus_Day per month.
My challenge is the Bus_Day column does not contain contiguous dates, so using DATEDIFF is not an option.
For this type of problem where you want to label non-contiguous dates, RANKX is your go-to unless you can solve it further upstream in your stack.
Here is a DAX column solution that adds a calculated column according to your specifications:
MTD Day =
VAR _yr = YEAR ( [Bus_Day] )
VAR _mth = MONTH ( 'Table'[Bus_Day] )
RETURN
RANKX (
FILTER (
'Table' ,
YEAR ( [Bus_Day] ) = _yr
&& MONTH ( [Bus_Day] ) = _mth
),
[Bus_Day] , , ASC
)
You can also calculate this using a measure, this formula does the trick with your sample data:
MTD Day Measure =
VAR _day = SELECTEDVALUE ( 'Table'[Bus_Day] )
VAR _tbl =
FILTER (
ALL ( 'Table' ) ,
YEAR ( 'Table'[Bus_Day] ) = YEAR ( _day )
&& MONTH ( 'Table'[Bus_Day] ) = MONTH ( _day )
)
RETURN
RANKX (
_tbl,
CALCULATE ( SELECTEDVALUE ( 'Table'[Bus_Day] ) ) , , ASC
)
Result:

Cumulative sum by months in Powerbi DAX

I want to show the cumulative sum per month, I have the number per month but need to show the sum up of previous months in each month..
I used the following measure:
RT FAC =
CALCULATE (
CALCULATE(SUM('Injuries'[Total]), 'Injuries'[Classification] = "FAC"),
FILTER(ALLSELECTED('Calendar Table'),
'Calendar Table'[Date]<= 'Calendar Table'[Date]))
But it gave me the total in all the months:
How can I show the running total such as:
What IF you try this with small change?
RT FAC =
VAR MaxDate =
MAX ( 'Calendar Table'[Date] )
RETURN
CALCULATE (
SUM ( 'Injuries'[Total] ),
FILTER (
ALL ( 'Injuries'[Classification] ),
'Injuries'[Classification] = "FAC"
),
FILTER ( ALLSELECTED ( 'Calendar Table' ), 'Calendar Table'[Date] <= MaxDate )
)

DATEADD throwing an error when adding MAX

I am looking to get the sum of sales for the last 3 months. not including the unfinished month which is this month.
I have this Dax but its not accepting the DATEADD with the MAX. Is there any workaround?
Measure1 = CALCULATE (
SUM ( table1[Sales] ),
DATESINPERIOD (
table1[date],
DATEADD( MAX ( table1[date] ), -1,MONTH),
-3,
MONTH
)
)
DATEADD function requires a set of dates to computation. That is why it not works with MAX, which returns single value. Find more here.
You need to find the maximum date in the dataset, then filter out the current month from the date table. Try the measure as follows:
Measure1 =
VAR maxDate =
CALCULATE(
MAX( 'Calendar'[Date] ),
ALL('Calendar' )
)
VAR firstDay = DATE( YEAR( maxDate ), MONTH( maxDate ), 1 )
VAR maxK =
CALCULATE(
MAX('Calendar'[Date] ),
'Calendar'[Date] < firstDay
)
VAR result =
CALCULATE(
SUM( AmountPaid[PaymentAmt] ),
DATESINPERIOD('Calendar'[Date], maxK, -3, MONTH )
)
return result
The maxK part calculates maximum date excluding the latest month in my dataset. You have to adjust the measure a bit for your needs (e.g. use TODAY() instead maxDate).
Hope it helps.

DAX Measure to Calculate Percentage of Customers with New Purchases Within One Year Sliding Window

I need a measure that will give me the percentage of customers during a calendar year who had new purchases within one year of their last purchase.
Normally I would just create a calculated column that captured the date of each customer's last purchase for each year, and then check to see if each customer from a given year had any purchases within a year of their respective last date, and then sum those up, but I'm using a live connection to a cube and can't create calculated columns.
Here's some pseudo-code of what I'm looking for:
One Year Return =
VAR Cohort =
SUMMARIZECOLUMNS (
Customer[ID],
FILTER (
VALUES ( Sales[Sales Date] ),
YEAR ( Sales[Sales Date] )
< ( YEAR ( TODAY () ) - 1 )
)
)
VAR Returners =
SUMMARIZECOLUMNS (
Customer[ID],
FILTER (
VALUES ( Sales[Sales Date] ),
Sales[Sales Date] > Sales[Old Sales Date] //<--Need help here
),
FILTER (
VALUES ( Customer[ID] ),
Customer[ID] IN Cohort
)
)
VAR Rate =
CALCULATE ( DISTINCTCOUNT ( Customer[ID] ), Customer[ID] IN Returners ) /
CALCULATE ( DISTINCTCOUNT ( Customer[ID] ), Customer[ID] IN Cohort )
RETURN
Rate
The main difficulty is that I need a different time window for each customer, but can't make a calculated column. I've been looking at using EARLIER or DATESBETWEEN or PARALLELPERIOD, but haven't been able to get any of them to work so far.
First I think you are looking for this
VAR last_year = DATE ( YEAR ( TODAY () ) - 1; MONTH ( TODAY () ); DAY ( TODAY () ) )
Second. The best way to get this done you need a bit of data modeling. The only way to make time intelligence work is to have a Date table. This table should have a row by day without missing days. You can search online how to create one or check my blog here.
Once you have this table releated on your model with your fact table you will be able to build that measure on a selected date. The selected one will be a value and last year of selected value the other one.
The crux is in the fact that you need to compare for each customer without a calculated column. It is possible by using the an iterator like COUNTX or SUMX. This enables you to loop through your customers in the cohort sub-table and create selections of your sales table by using the customer ID in the current iteration to filter your sales table using EARLIER. For each customer in the cohort you then select their last purchase date and the one before that and compare the two to see if they followed within the year.
In DAX it looks a bit complex but I tried to make it spacier so it is easier to follow. It also contains a little workaround for the fact that you cannot simply loop over the _cohort variable as you won't have access to the customer ID in the current iteration in that case
One year return =
var _now = TODAY()
var _cohort =
SUMMARIZECOLUMNS (
Sales[CustomerID] ;
FILTER (
Sales ;
DATEDIFF( Sales[SalesDate] ; _now ; YEAR ) <= 1
)
)
var _countCohort = COUNTROWS( _cohort )
var _countReturns =
SUMX (
SUMMARIZECOLUMNS (
Sales[CustomerID] ; FILTER ( Sales ; Sales[CustomerID] IN _cohort )
) ;
var _lastPurchase =
CALCULATE (
MAX ( Sales[SalesDate] ) ;
ALLSELECTED ( Sales ) ;
Sales[CustomerID] = EARLIER( Sales[CustomerID] )
)
var _preLastPurchase =
CALCULATE (
MAX ( Sales[SalesDate] ) ;
ALLSELECTED ( Sales ) ;
Sales[SalesDate] < _lastPurchase ;
Sales[CustomerID] = EARLIER( Sales[CustomerID] )
)
RETURN
IF ( DATEDIFF( _preLastPurchase ; _lastPurchase ; YEAR ) <= 1 ; 1 ; 0 )
)
RETURN
_countReturns / _countCohort
I ended up importing a dataset from the cube and creating calculated columns to get me there after all. #jelle-hoekstra's answer looks close to what I ended up doing, but I couldn't figure out how to get his measure to run.
I made three calculated columns and did a distinct count on the ReturnCustomerID column to get the number of customers who returned within one year of their last purchase:
Last Purchase Date =
MINX (
FILTER (
Sales,
Sales[Sales Year]+1 = EARLIER ( Sales[Sales Year] ) && Sales[CustomerID] = EARLIER ( Sales[CustomerID] )
),
MAXX (
FILTER (
Sales,
Sales[Sales Year] = EARLIER ( Sales[Sales Year] ) && Sales[CustomerID] = EARLIER ( Sales[CustomerID] )
),
Sales[Sales Date]
)
)
One Year Date =
MINX (
FILTER (
Sales,
Sales[Sales Year]+1 = EARLIER ( Sales[Sales Year] ) && Sales[CustomerID] = EARLIER ( Sales[CustomerID] )
),
MAXX (
FILTER (
Sales,
Sales[Sales Year] = EARLIER ( Sales[Sales Year] ) && Sales[CustomerID] = EARLIER ( Sales[CustomerID] )
),
EDATE (Sales[Sales Date], 12 )
)
)
ReturnCustomerID =
IF (
Sales[Sales Date] > Sales[Last Purchase Date] && Sales[Sales Date] < Sales[One Year Date], Sales[CustomerID], BLANK()
)

DAX - Calculate sum of the last 365 days

I want to calculate the sum of sales of the last 365 days.
The following function works very well if there is a day filter in the visual (chart, table, etc.).
But - and this is where the problem lies - if there's not a day filter, but a month for example, then the measure returns the sales of the last 12 months.
So, today (9.11.2017), I should get the sum of the sales from 9.11.2016 until 8.11.2017 - regardless of what filter is applied.
And not the sum of the sales from 1.12.2016 until 30.11.2017.
SalesTTM =
IF (
TODAY () >= FIRSTDATE ( 'calendar'[date] );
CALCULATE (
'order'[Sales];
DATESBETWEEN (
'calendar'[date];
NEXTDAY ( SAMEPERIODLASTYEAR ( LASTDATE ( 'calendar'[date] ) ) );
LASTDATE ( 'calendar'[date] )
)
)
)
In the DATESBETWEEN function above I can't find a way to express "tomorrow less one year" until "today".
How can I do that?
You need to put something in there to ignore the filtering on the month. Try inserting ALL('calendar'[date]); before your DATESBETWEEN ( line.
SalesTTM =
VAR LastDate = LASTDATE ( 'calendar'[date] )
RETURN IF (
TODAY () >= FIRSTDATE ( 'calendar'[date] );
CALCULATE (
'order'[Sales];
ALL('calendar'[date]);
DATESBETWEEN (
'calendar'[date];
NEXTDAY ( SAMEPERIODLASTYEAR ( LastDate ) );
LastDate
)
)
)