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
)
)
)
Related
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 )
)
I have a typical rolling 12 months Dax measure as :
R12M :=
CALCULATE (
[Income],
DATESBETWEEN (
Calendar[Date],
NEXTDAY ( SAMEPERIODLASTYEAR ( LASTDATE ( Calendar[Date] ) ) ),
LASTDATE ( 'Calendar'[Date] )
)
)
The problem is that our Calendar table only starts from a certain date, so anything which is in the first year does not link to the calendar. So I want to start the measure from a year after the minimum date on our calendar. What is the best way to achieve this?
I hope you found your answer by now, but in case still looking then try like,
R12M :=
CALCULATE (
[Income],
DATESBETWEEN (
Calendar[Date],
NEXTDAY ( SAMEPERIODLASTYEAR ( LASTDATE ( Calendar[Date] ) ) ),
LASTDATE ( 'Calendar'[Date] )
),
FILTER ( CALENDER, DATE >= DATEADD ( FIRSTDATE ( DATE ), 1, YEAR ) )
)
I am using a measure below to display the months from fact table as described here:
Billings12Months =
CALCULATE (
SUM ( 'Datatable'[Allowable] ),
DATESINPERIOD ( DimDate[Date], MIN ( DimDate[Date] ), +12, MONTH )
)
My attempt to get the running total of above measure is failing:
BillingsRunningTotal =
CALCULATE (
[Billings12Months],
FILTER ( ALLSELECTED ( DimDate ), DimDate[Date] <= MAX ( DimDate[Date] ) )
)
BillingsRunningTotal2 =
SUMX (
FILTER (
ALLSELECTED ( DimDate[Date] ),
DimDate[Date] <= MAX ( ( DimDate[Date] ) )
&& YEAR ( DimDate[Date] ) = YEAR ( MIN ( DimDate[Date] ) )
),
[Billings12Months]
)
[BillingsRunningTotal] return same values as [Billings12Months] (please see screen 1 attached) and
[BillingsRunningTotal2] return wrong values and month start from Jan, 17 instead of May, 17 (please see screen-2)
Please help me to calculate the running total. If possible please describe how your solution is working so that I can be better in DAX.
Update:
Please see the screen-3 below for the output when I use the measure suggested by Kosuke:
BillingsRunningTotal =
CALCULATE (
SUM ( Datatable[Allowable] ),
FILTER ( ALLSELECTED ( DimDate ), DimDate[Date] <= MAX ( DimDate[Date] ) )
)
The months are from fact table (not from a Date table) and I think DATESINPERIOD plays a role to calculate and display the months. When we use SUM ( Datatable[Allowable] ), there would be a single month as dictated by the slicer. So we need to use DATESINPERIOD with rolling month calculation logic (DimDate[Date] <= MAX ( DimDate[Date] )) or virtually sum the [Billings12Months], It is where I am failing.
Thanks
You are almost there with the first attempt, however what to calculate is not [Billings12Months], but SUM( Datatable[Allowable] ).
BillingsRunningTotal =
CALCULATE (
SUM ( Datatable[Allowable] ),
FILTER ( ALLSELECTED ( DimDate ), DimDate[Date] <= MAX ( DimDate[Date] ) )
)
Essentially, [Billings12Months] and [BillingsRunningTotal] are same in calculating the sum of Datatable[Allowable], but the only difference is each measure calculates for different scope of period. Therefore, the right way of thinking is to wrap SUM ( Datatable[Allowable] ) in CALCULATE, with different filter parameters.
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()
)
After going through several posts on StackOverflow and the PowerBI forums, I still can't figure out how to calculate a rolling average based on a given period- in my case, a 30-day rolling average.
Most of the posts I've seen advocate something either identical or really similar to this:
Rolling Sum :=
CALCULATE (
[Sales],
FILTER (
ALL ( Sales ),
[Date]
>= MAX ( Sales[Date] ) - 365
&& [Date] <= MAX ( Sales[Date] )
)
)
(code taken from this post)
...and yet, I can't seem to get the proper values.
In my case, I have the following:
"closing date" for a given loan (column)
loan count (measure)
closing length (column)- length of time (in days) to close a loan
What I'd like to calculate is the rolling 30 day average for any given day. I coded the following:
Rolling Average =
CALCULATE (
SUM(Query1[Closing_Length])/[Loan Count],
FILTER (
ALL ( Query1 ),
[Closing Date].[Date]
>= MAX ( Query1[Closing Date] ) - 30
&& [Closing Date] <= MAX ( Query1[Closing Date] )
)
)
To check the results, I used a visual filter to examine one month's worth of data and these are the results:
Note the totals row at the bottom; for this given period, there are 102 loans and it took an aggregate of 3922 days for them to close. The average I'd like to calculate is 3922/102, which should equal approximately 38.45 days. Instead, we see 42.
How can I fix this?
Measure based solution:
Rolling Average Measure =
VAR A =
SUMX (
FILTER (
ALL ( 'Query' ),
'Query'[Closing Date] <= MAX ( 'Query'[Closing Date] )
),
ROUND ( 'Query'[Closing Length], 2 )
)
VAR B =
SUMX (
FILTER (
ALL ( 'Query' ),
'Query'[Closing Date] <= MAX ( 'Query'[Closing Date] )
),
ROUND ( 'Query'[Loan Count], 2 )
)
RETURN
A / B
Calculated column based solution:
Rolling Average =
VAR CurrentDate = 'Query'[Closing Date]
VAR T =
FILTER ( 'Query', [Closing Date] <= CurrentDate )
RETURN
ROUND ( SUMX ( T, 'Query'[Closing Length] ) / SUMX ( T, [Loan Count] ), 2 )
Print Screen: