I'm fairly new to Power bi and have tried and searched for this almost all the forums but couldn't find anything similar to mine.
So.. I have a table like the following (Something similar)
I would like to calculate the retention rate of the users (who actually came back).
What I have done so far:
RetentionRate = (ReturningUsers / PreviousDayDistinctUsers)*100%
ReturningUsers = DistinctUsers - NewUsers
PreviousDayDistinctUsers = CALCULATE(DISTINCTCOUNT(table[User], PREVIOUSDAY(table[Date])
NewUsers = CALCULATE(DISTINCTCOUNT(table[User] ), table[MonthlyNewUsers] = BLANK () )
The above looks to be working, but the only drawback was with the PreviousDayDistinctUsers as it is only considering the previous day (Not all the days from the starting to that day).
So how do I write a measure to calculate the DistinctUsers for all the days until today?
PreviousDayDistinctUsers =
VAR Current_Day = LASTDATE ( table[Date] )
RETURN
CALCULATE ( DISTINCTCOUNT ( table[User] ), table[Date] < Current_Day )
How it works:
First, save last date in a filter context into a variable (instead of LASTDATE, you can also use MAX function).
Second, filter table User by all dates that are less than the saved date, and count distinct users in the filtered table.
Related
I have a quite peculiar problem. I have a column with values that represents the state of Inventory for each Site (category).
Which means that the most recent one value for each month is always last day per each site per month.
Example
for site 667 for november its going to be value 5 252 235.74 (31/12/2021) but for site 200 its going to be 79 967 894.18 (30/12/2021)
he sum of those values should be 85 220 129.92 which is state of inventory for those two sites per december.
I was able to calculate this with this measure
Inventory Cost =
VAR _pretable =
ADDCOLUMNS (
SUMMARIZE (
v_factinventorytransactions,
v_dimdate[DateId],
v_factinventorytransactions[SiteId]
),
"InventoryCost", CALCULATE ( AVERAGE ( v_factinventorytransactions[RunningCost] ) )
)
VAR _table =
FILTER (
_pretable,
VAR _MaxDate =
CALCULATE (
MAX ( v_factinventorytransactions[InventoryTransactionDateId] ),
ALLSELECTED ( v_dimdate[DateId] )
)
RETURN
v_dimdate[DateId] = _MaxDate
)
RETURN
SUMX ( _table, [InventoryCost] )
Which works perfectly but I'm wondering if it can be simplyfied. I want it to simplify, because when I want to use this measure inside another one that sums those Inventory Cost values per month for last 3 months and I have wrong answers.
Which means that this Inventory Cost measure works but if I call out this measure in the one below it shows wrong numbers (but other measures, more simply ones work).
Rolling3Months =
VAR _EndDate = MAX(v_dimdate[Date])
VAR _Dates = DATESINPERIOD(v_dimdate[Date], _EndDate, -3, MONTH)
VAR _Cost = [Inventory Cost]
VAR _Inventory = SUMX(_Dates, CALCULATE(_Cost, ALL(v_dimdate[YearMonth])))
RETURN
_Inventory
I'm a little bit stuck and would be super appreciated when someone would pointed out my mistakes/errors here.
I'm also providing sample power BI file with those.
https://wetransfer.com/downloads/cabd5902e1491b6874064a0deb26d0ae20220614185839/dac3e16acdce4c2b707e92bd56a04d1020220614185904/77a258
Thank you
I'm new to Power BI and DAX.
I want to show the total ID count of this year and the total ID counts of previous years at the same dates each of which is associated with a different Category_Number.
The below tables show the original data set (1st table) and the result table (2nd table) I would like to have.
enter image description here
enter image description here
Any ideas or suggestions will be greatly appreciated.
Thanks!
You want to filter and use SAMEPERIODLASTYEAR.
To get the values of one category you can do:
Category_Nbr 80 = CALCULATE(COUNTROWS(myTable),myTable[Category_Nbr] = 80)
for the value of this but for the previous year you could use your DATE TABLE if you have it, if not, use the automatic one. I'll assume you don't have one so use the automatic.
Category_Nbr 80 LY = CALCULATE([Category_Nbr 80],SAMEPERIODLASTYEAR(myTable[Effective_Date].Date))
With this you can do a comparison over time
Category_Nbr Count YoY = DIVIDE([Category_Nbr 80 LY]-[Category_Nbr 80],[Category_Nbr 80 LY])
You can just adapt the filter for other categories.
Consider having a look into Quick Measures really nice way to start learning DAX.
Below are two measures I created.
The Total_ID measure works well. It shows the total number of IDs that have the Category_Number =80 and Effecitve_Date < Today.
The Total_ID_LY measure shows the total number IDs that have the Category_Number = 70, but doesn't show the Effective_Date< The same data last year.
I want the Total_ID_LY measure to have two filters, Category_Number = 70 (80-10) and Effective_Date < The same data last year of today.
Any helps?
Thanks!
Total_ID = COUNT('myTable'[ID])
Total_ID_LY =
VAR CurrentCategory = SELECTEDVALUE ( 'myTable'[Category_Number] )
VAR PreviousCategory =
CALCULATE (
MAX ( 'myTable'[Category_Number] ),
ALLSELECTED ( 'myTable' ),
KEEPFILTERS ( 'myTable'[Category_Number] < CurrentCategory )
)
VAR Result =
CALCULATE (
[Total_ID],
'myTable'[Category_Number] = PreviousCategory
)
RETURN
Result
I have a summarize table that is summed by the Date and Building_Name. I am trying to figure out how to add an increase/ decrease column like my table below. I want to show if the 'total unsigned' has increased from day to day for each building.
I cannot get a formula that will take the previous days total for one building - current days # of total unsigned. Trying to get the forth column for my report.
I can get it to work if I am just showing day over day change if I am not also trying to add the Building_name to the table.
Unsigned Prev Day =
VAR CurrentDay = SELECTEDVALUE(SummarizeTable[Day Number])
VAR CurrentMonth = SELECTEDVALUE(SummarizeTable[Month Number])
VAR MaxDayNumber = CALCULATE(MAXA(SummarizeTable[Day Number]))
Return SUMX(
FILTER(ALL(SummarizeTable),
IF( CurrentDay = 1,
SummarizeTable[Day Number] = MaxDayNumber && SummarizeTable[Month Number]= CurrentMonth-1,
SummarizeTable[Day Number] = CurrentDay -1)),
[Total Unsigned])
Edit:
Thank you for the help, you definitely put me on the right track. This is the formula I ended up using. Thank you again for the help!
Unsigned Prev Day =
VAR MostRecentDate = MAX ( 'SummarizeTable'[Date] )
RETURN
CALCULATE (
[Total Unsigned],
ALL ( 'SummarizeTable'[Date], 'SummarizeTable'[Day Number], 'SummarizeTable'[Month Number] ),
'SummarizeTable'[Date] = MostRecentDate - 1
)
This assumes that you have or can make a column, 'SummarizeTable'[Date]. If you already have month and day, this should be trivial. This solution takes advantage of the fact that DAX has well-behaved arithmetic on dates.
Additionally, you should look at building a date dimension, rather than doing all of this out of a single table. It will ultimately make your life a lot easier. There are a bunch of good date dimensions out there, but I'm partial to mine.
EDIT: Per discussion in comments the goal is to add this as a calculated column to a data table. The definition above is intended to be used as a measure.
# Increase/ Decrease =
CurrentRowDate = 'SummarizeTable'[Date]
RETURN
CALCULATE (
SUM ( 'SummarizeTable'[Total Unsigned] ),
ALLEXCEPT ( 'SummarizeTable'[Building] ),
'SummarizeTable'[Date] = CurrentRowDate - 1
)
This will add a column to 'SummarizeTable' that has the sum of [Total Unsigned] for the same value of [Building] as is on the current row and with a date 1 less than that on the current row.
I have following scenario which has been simplified a little:
Costs fact table:
date, project_key, costs €
Project dimension:
project_key, name, starting date, ending date
Date dimension:
date, years, months, weeks, etc
I would need to create a measure which would tell project duration of days using starting and ending dates from project dimension. The first challenge is that there isn't transactions for all days in the fact table. Project starting date might be 1st of January but first cost transaction is on fact table like 15th on January. So we still need to calculate the days between starting and ending date if on filter context.
So the second challenge is the filter context. User might want to view only February. So it project starting date is 1.6.2016 and ending date is 1.11.2016 and user wants to view only September it should display only 30 days.
The third challenge is to view days for multiple projects. So if user selects only single day it should view count for all of the projects in progress.
I'm thankful for any help which could lead towards the solution. So don't hesitate to ask more details if needed.
edit: Here is a picture to explain this better:
Update 7.2.2017
Still trying to create a single measure for this solution. Measure which user could use with only dates, projects or as it is. Separate calculated column for ongoing project counts per day would be easy solution but it would only filter by date table.
Update 9.2.2017
Thank you all for your efforts. As an end result I'm confident that calculations not based on fact table are quite tricky. For this specific case I ended up doing new table with CROSS JOIN on dates and project ids to fulfill all requirements. One option also was to add starting and ending dates as own lines to fact table with zero costs. The real solution also have more dimensions we need to take into consideration.
To get the expected result you have to create a calculated column and a measure, the calculated column lets count the number of projects in dates where projects were executed and the measure to count the number of days elapsed from [starting_date] and [ending_date] in each project taking in account filters.
The calculated column have to be created in the dim_date table using this expression:
Count of Projects =
SUMX (
FILTER (
project_dim,
[starting_date] <= EARLIER ( date_dim[date] )
&& [ending_date] >= EARLIER ( date_dim[date] )
),
1
)
The measure should be created in the project_dim table using this expression:
Duration (Days) =
DATEDIFF (
MAX ( MIN ( [starting_date] ), MIN ( date_dim[date] ) ),
MIN ( MAX ( [ending_date] ), MAX ( date_dim[date] ) ),
DAY
)
+ 1
The result you will get is something like this:
And this if you filter the week using an slicer or a filter on dim_date table
Update
Support for SSAS 2014 - DATEDIFF() is available in SSAS 2016.
First of all, it is important you realize you are measuring two different things but you want only one measure visible to your users. In the first Expected result you want to get the number of projects running in each date while in the Expected results 2 and 3 (in the OP) you want the days elapsed in each project taking in account filters on date_dim.
You can create a measure to wrap both measures in one and use HASONEFILTER to determine the context where each measure should run. Before continue with the wrapping measure check the below measure that replaces the measure posted above using DATEDIFF function which doesn't work in your environment.
After creating the previous calculated column that is required to determine the number of projects in each date, create a measure called Duration Measure, this measure won't be used by your users but lets us calculate the final measure.
Duration Measure = SUMX(FILTER (
date_dim,
date_dim[date] >= MIN ( project_dim[starting_date] )
&& date_dim[date] <= MAX ( project_dim[ending_date] )
),1
)
Now the final measure which your users should interact can be written like this:
Duration (Days) =
IF (
HASONEFILTER ( date_dim[date] ),
SUM ( date_dim[Count of Projects] ),
[Duration Measure]
)
This measure will determine the context and will return the right measure for the given context. So you can add the same measure for both tables and it will return the desired result.
Despite this solution is demonstrated in Power BI it works in Power Pivot too.
First I would create 2 relationships:
project_dim[project_key] => costs_fact[project_key]
date_dim[date] => costs_fact[date]
The Costs measure would be just: SUM ( costs_fact[costs] )
The Duration (days) measure needs a CALCULATE to change the filter context on the Date dimension. This is effectively calculating a relationship between project_dim and date_dim on the fly, based on the selected rows from both tables.
Duration (days) =
CALCULATE (
COUNTROWS ( date_dim ),
FILTER (
date_dim,
date_dim[date] >= MIN ( project_dim[starting_date] )
&& date_dim[date] <= MAX ( project_dim[ending_date] )
)
)
I suggest you to separate the measure Duration (days) into different calculated column/measure as they don't actually have the same meaning under different contexts.
First of all, create a one-to-many relationship between dates/costs and projects/costs. (Note the single cross filter direction or the filter context will be wrongly applied during calculation)
For the Expected result 1, I've created a calculated column in the date dimension called Project (days). It counts how many projects are in progress for a given day.
Project (days) =
COUNTROWS(
FILTER(
projects,
dates[date] >= projects[starting_date] &&
dates[date] <= projects[ending_date]
)
)
P.S. If you want to have aggregated results on weekly/monthly basis, you can further create a measure and aggregate Project (days).
For Expected result 2 and 3, the measure Duration (days) is as follows:
Duration (days) =
COUNTROWS(
FILTER(
dates,
dates[date] >= FIRSTDATE(projects[starting_date]) &&
dates[date] <= FIRSTDATE(projects[ending_date])
)
)
The result will be as expected:
I've been struggling with DAX while creating a model to publish on Power BI and the actual problem is presented on the image here. Basically I need a column that shows the value from the predecessor time for the same id.
I did with ranking but wanted to know if it is possible to make it better.
How would you guys do it?
Rank = COUNTROWS(FILTER(test; [id] = EARLIER([id]) && [Date] <= EARLIER([Date])))
Past = if(test[Rank]=1;0; LOOKUPVALUE(test[qt];teste[Rank];test[Rank]-1;test[id];test[id]))
This is a solution tested with the basic model you posted, I don't guarantee this is a machine low cost expression but you can give it a try.
I've created a column called PREVIOUS in which is calculated the previous qty for every row based on the date for the same id.
PREVIOUS =
CALCULATE (
MAX ( TableName[qt] ),
FILTER (
TableName,
EARLIER ( TableName[id] ) = TableName[id]
&& EARLIER ( TableName[date] ) > TableName[date]
)
)
The following is a Power BI table using the PREVIOUS column.
Let me know if this helps.