I am looking to build a column chart in Power BI that displays cumulative sales by month up to max date selected in date slicer. I have a supplementary Date2 table that is related to Date table (inactive relation). Tried something like this, but I keep getting all the months irrespective which one is selected in slicer:
Sales to date selected =
VAR ReferenceDate = MAX ( 'Date'[Date] )
Return
CALCULATE ( [SalesAmount],
ALLEXCEPT('Date', 'Date'[Year]),
FILTER( all(Date2[Date]), Date2[Date] <= MAX( Date2[Date] )
&& Date2[Date] <= ReferenceDate),
USERELATIONSHIP ( 'Date'[Date], Date2[Date] )
)
This is what I get as a result (Slicer selects month 7):
It looks like CALCULATE does not honor filter Date2[Date] <= ReferenceDate . What am I doing wrong here?
OK, looks like this scenario solves my issue. I removed inactive relationship between Date and Date2 and introduced active relationship from Sales to Date2.
Sales to date selected =
VAR ReferenceDate = MAX ( 'Date'[Date] )
Return
IF( MAX(Date2[Date]) <= ReferenceDate,
CALCULATE ( [SalesAmount],
ALLEXCEPT('Date', 'Date'[Year]),
Date2[Date] <= MAX( Date2[Date] )
)
)
I made a correction to your code; but It seems that It takes a long time for it to be approved by community members:
So test this:
Sales to date selected =
VAR ReferenceDate =
MAX ( ALLSELECTED ( 'Date2'[Date] ) )
RETURN
CALCULATE (
[SalesAmount],
FILTER ( ALLEXCEPT ( 'Date2', 'Date2'[Year] ), 'Date2'[Date] <= ReferenceDate )
)
Or This:
Sales to date selected =
VAR ReferenceDate =
MAX ( ALLSELECTED ( 'Date2'[Date] ) )
RETURN
CALCULATE (
[SalesAmount],
FILTER ( ALL ( 'Date2'[Date] ), 'Date2'[Date] <= ReferenceDate )
)
Related
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:
I have the following dataset
user_id, login_date
111, 01/02/2021
222, 02/15/2021
444, 02/20/2021
555, 01/15/2021
222, 03/10/2021
444, 03/11/2021
I want to count of the number of unique active user_id in the last 90 days based on the max date of my date slicer. I'd like to solve this without using filters. This also needs to be dynamic as max date can be change from the date slicer.
From what I have understand so far I will need to evaluate for each row if the date difference between the current date of the row and the max date of the slicer is less than 90 days. Then for all the rows where the date diff is less than 90 days I will want to count the distinct number of users.
so basically I will have three layer in my final formula
evaluate the date diff.
filter out rows where the date diff is superior to 90 days.
count the distinct users in the remaining rows.
I've tried many approach and formula. I think that this one is closed to something that could work:
Measure test = CALCULATE(SUMX(DISTINCT(mytable[user_id]),filter(mytable,DATEDIFF(SELECTEDVALUE(mytable[login_date]),[Max range date],DAY)>90)))
this formula return me the following error :
The expression refers to multiple columns. Multiple columns cannot be converted to a scalar value.
I've also tried applying a if statement to output the date diff as 0 and 1 and hopefully being able to sum this for each unique id with something like this
SUMX( VALUES(my_table[user_id]), IF(DATEDIFF(SELECTEDVALUE(mytable[login_date]),[Max range date],DAY)>90,0,1)
anyway I'm kind of stuck. hopefully my question is clear enough.
You will have to create a disconnected table from which you will use the date column in the slicer, I have prepared a power BI file which included 2 very common scenarios, I hope that helps you.
File - Simon.pbix
Screenshot of the report - https://ibb.co/xjrjVv5
Screenshot of the model - https://ibb.co/Ws1z8D7
DAX Code -
for simon =
IF (
ISINSCOPE ( simon[Login Date] )
|| ISINSCOPE ( simon[User ID] ),
VAR LastVisibleDate =
CALCULATE (
MAX ( 'Simon Date Table'[Login Date] ),
ALLSELECTED ( 'Simon Date Table' )
)
VAR CurrentDate =
MAX ( simon[Login Date] )
VAR TimeJump = 90
VAR Result =
CALCULATE (
DISTINCTCOUNT ( simon[User ID] ),
simon[Login Date] <= LastVisibleDate,
simon[Login Date] > LastVisibleDate - TimeJump,
ALLSELECTED ( simon )
)
RETURN
Result
)
second version:
for simon 2 =
IF (
ISINSCOPE ( simon[Login Date] )
|| ISINSCOPE ( simon[User ID] ),
VAR LastVisibleDate =
CALCULATE (
MAX ( 'Simon Date Table'[Login Date] ),
ALLSELECTED ( 'Simon Date Table' )
)
VAR CurrentDate =
MAX ( simon[Login Date] )
VAR TimeJump = 90
VAR Result =
IF (
CurrentDate <= LastVisibleDate,
CALCULATE (
DISTINCTCOUNT ( simon[User ID] ),
simon[Login Date] <= CurrentDate,
simon[Login Date] > CurrentDate - TimeJump,
ALLSELECTED ( simon )
)
)
RETURN
Result
)
I am trying to create new measures that will only show the data value of the Last day every month and another measure will show the data value of every week Saturday in Power BI.
Many thanks in Advance.
The data is continuing and the next series of data will appended data wise
Output:
Need to create a measure which will show only last day of the Week value ( Example- Saturday is my Last of the Week and Count numbers I need to see as output)
Similarly for Month - Last day of the Month I need to see the Numbers of each service.
Do you have Calendar table mark as "Date Table", which is connected by relationship to your Table? If so, then you can use ENDOFMONTH ( 'Calendar'[issue_date] ) to get lastDateOfMonth
then simply:
ShowValueAtLastDayOfMonth =
calculate( sum(Table[Total sale]),
KEEPFILTERS(
filter(ALL('Calendar'[issue_date]),
'Calendar'[issue_date] = ENDOFMONTH ( 'Calendar'[issue_date] )
)
)
)
ShowOnlyOnSaturday =
calculate(sum(Table[Total sale]), KEEPFILTERS( FLITER(ALL('Calendar[issue_date]),
WEEKDAY ( SELECTEDVALUE('Calendar'[issue_date])) = 7 )))
Without a "Date Table" we need to replace 'Calendar'[issue_date] with your Table[Date] and ENDOFMONTH with:
VAR LastDateVisible =
CALCULATE ( MAX ( 'Table'[Date] ) )
VAR LastYearVisible =
YEAR ( LastDateVisible )
VAR LastMonthVisible =
MONTH ( LastDateVisible )
VAR DaysInMonth =
FILTER (
ALL ( 'Table'[Date] ),
YEAR ( 'Table'[Date] ) = LastYearVisible
&& MONTH ( 'Table'[Date] ) = LastMonthVisible
)
VAR LastDayInMonth =
MAXX (
DaysInMonth,
'Table'[Date]
)
VAR Result =
CALCULATETABLE (
VALUES ( 'Table'[Date] ),
'Table'[Date] = LastDayInMonth
)
RETURN
Result
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()
)
I want to filter my report to only get data for every current month in the current year based on the date column in powerbi. how do I create a measure to do this?
Try something like:
ThisMonthMeasure =
CALCULATE (
[MyMeasure],
FILTER (
'Calendar',
MONTH ( 'Calendar'[Date] ) = MONTH ( NOW() ) &&
YEAR ( 'Calendar'[Date] ) = YEAR ( NOW() )
)
)