Power BI: Use unrelated date table to create a measure - powerbi

Hi I have been struggling with this for a bit now and I hope I didn't miss a previous question. I am trying to get a count of the vehicles we have based on an EOMONTH date. We are buying and selling cars on a regular basis and for reporting we need to know how many we had at the end of each month and the report is a rolling 12 months.
I've tried creating the relationship with the purchasedate of the vehicle to the date of my date table but when I create the measure (Used to calculate the number of vehicles purchased but haven't been sold):
SalesBlank = CALCULATE(
COUNT(Vehicles[MVANumber]),
FILTER(Vehicles, Vehicles[purchasedate] <= RELATED('Date'[EOMONTH]) && ISBLANK(Vehicles[saledate])))
I only get a count of vehicles purchased that month and don't have a sale date - I'm not surprised because my relationship with the date table is the purchase date.
How can I set up a measure to look at the date table and filter the vehicles table with this logic:
purchasedate <= date[EOMONTH] && ISBLANK(salesdate)
Any help would be greatly appreciated!!
Thanks,
Matt
Sample Data and Desired Results
Relationships

If I understand you correctly, you want to get a count of the vehicles on hand at the end of each month. That could be calculated by counting the vehicles with a purchase date less than or equal to the selected end of month and subtracting the count of vehicles with a sale date less than or equal to the selected end of month.
You can create an active relationship between Vehicle[PurchaseDate] and Date[Date]. Then create an inactive relationship based upon Vehicles[SaleDate] and Date[Date].
You could use a measure that is something like this:
Inventory Count =
VAR MaxDate =
MAX ( 'Date'[Date] )
VAR MinDate =
CALCULATE ( MIN ( 'Date'[Date] ), ALL ( 'Date' ) )
VAR Purch =
CALCULATE (
COUNT ( 'Vehicles'[VehicleID] ),
DATESBETWEEN ( 'Date'[Date], MinDate, MaxDate )
)
VAR Sales =
CALCULATE (
COUNT ( 'Vehicles'[VehicleID] ),
USERELATIONSHIP ( 'Date'[Date], Vehicles[Sale Date] ),
DATESBETWEEN ( 'Date'[Date], MinDate, MaxDate )
)
VAR MaxPurDt =
CALCULATE ( MAX ( 'Vehicles'[Purchase Date] ), ALL ( 'Vehicles' ) )
VAR MaxSlDt =
CALCULATE ( MAX ( 'Vehicles'[Sale Date] ), ALL ( 'Vehicles' ) )
RETURN
IF (
MIN ( 'Date'[Date] ) <= MaxPurDt
|| MIN ( 'Date'[Date] ) <= MaxSlDt,
Purch - Sales
)
This measure gets a cumulative count of purchases and a cumulative count of sales and then subtracts them. The IF check is to avoid propagation of cumulative totals beyond the maximum date in the Vehicle table.
I'm not sure how to interpret your showing of just 3 months in the desired results. This will produce the same answers as what you have, but without a filter applied to the table, it starts at 3/31/2016 (the date of the first sale).
Edit: There's probably a more efficient way along the lines you were thinking, but it is escaping me at the moment.

Related

Use RankX based on a measure with dynamic max date

I have a data set of game logs for a basketball season. I want to do a ranking for a statistic comparing all teams, but only up to the current date of that specific row. Since not every team plays every day, the current row should be the max date and it should rank based on the most recent value up to that date. I have a measure that does the correct calculation:
LatestTmDVP =
VAR thisdate =
MAX ( [DATE] )
VAR maxdate =
CALCULATE ( MAX ( [DATE] ), ALLSELECTED ( 'NBA-PLAYER-FEED'[DATE] ) )
VAR result =
CALCULATE (
MAX ( 'NBA-PLAYER-FEED'[TmDVPoToDt] ),
'NBA-PLAYER-FEED'[DATE] = maxdate
)
RETURN
IF ( thisdate = maxdate, result )
If I put this in a report with a date slicer, I can see that it is working correctly:
So I need to get this measure into a column, with the max date set as the date of the current row, and then do a rank based on that, but I just can't get the RankX syntax right for this. Appreciate any help!

Dax Counts at end of each month

I have a measure that depending on a "before" date slicer shows how many accounts were active at any given point in the company's history. I'm being asked to show month over month growth (end of month 1 compared to end of month 2 totals) but that's difficult given my measure needs a date slicer with one date value to return a total.
Active_Accounts =
CALCULATE (
COUNTX (
FILTER (
VALUES ( 'TEST CHARGES'[BI_ACCT] ),
[total as of date] > 0
),
[BI_ACCT]
)
)
link to sample file
https://www.dropbox.com/s/pewpm85wogvq3xf/test%20active%20charges.pbix?dl=0
if you move the slider you'll see the active accounts total change to show at that time in history how many accounts had an active charge. What I'm hoping to add to the dashboard is a measure that can be placed on a table of month end values and show the active accounts at that time so I can do month to month comparisons.
Active Accounts =
var month_end =
ENDOFMONTH (
LASTNONBLANK (
'Test Charges Date Table'[Date],
CALCULATE ( DISTINCTCOUNT( ( 'TEST CHARGES'[BI_ACCT] ) )
)
)
)
var last_date =
CALCULATE(
LASTNONBLANK('TEST CHARGES'[CHG_DATE], ""),
'TEST CHARGES'[CHG_DATE] <= max('Test Charges Date Table'[Date])
)
var num_of_actives =
CALCULATE(
Countx(
Filter(
Values('TEST CHARGES'[BI_ACCT]),
[total as of date] > 0
) , [BI_ACCT]
),
last_date <= month_end
)
return num_of_actives
As Peter advices you do not need Calculate() to show total in the card and using of Calculate() reduces speed of calculation. In your case speed is reduced with no reason.
There are no need to have a special column for month - use date hierarchy for row and just exclude day and quater levels.
Then add the measure to the visual table/matrix
Cummulative Count =
Calculate(
[Active_Accounts]
,'Test Charges Date Table'[Date]<=MAX('Test Charges Date Table'[Date])
)
Cummulative Count prevMonth =
Calculate(
[Cummulative Count]
,PARALLELPERIOD('Test Charges Date Table'[Date],-1,MONTH)
)

Days between orderdates per Customer and first order value

I am new to DAX and have 2 questions I would like answered for a project. I am working on figuring out what the first value per customer is so what amount does the customer come in with.
In addition I would like to know what is the time between customer's orders does the customer come back to buy something after a day, week or only after a year. And if a customer comes 5 times what is the time between the orders each time.
Data set
enter image description here
Now I tried the following but then I only get the first date back each time but then each customer gets the very first order date that exists.
First Order = CALCULATE(FIRSTDATE(Text[Datum].[Date]),VALUES(Text[Datum].[Date]))
How can I solve this two question with DAX
You can try the following:
Initial value for customer measure
Initial value =
-- find customers first appearance date
VAR first_date =
CALCULATETABLE (
FIRSTDATE ( 'Table'[Date] ),
-- remove all filters on 'Table'[Date]
REMOVEFILTERS ( 'Table'[Date] )
)
RETURN
CALCULATE (
SUM ( 'Table'[Value] ),
first_date
)
First order date measure
First Order =
CALCULATE (
FIRSTDATE ( 'Table'[Date] ),
REMOVEFILTERS ( 'Table'[Date] )
)
Days passed since last visit measure
Days passed =
VAR last_visit =
CALCULATE (
MAX ( 'Table'[Date] ),
'Table'[Date]
-- from example expecting Customer ID & Date form unique combination,
-- otherwise use MAX() instead
< SELECTEDVALUE ( 'Table'[Date] )
)
RETURN
DATEDIFF (
last_visit,
-- same here as above with SELECTEDVALUE()
SELECTEDVALUE ( 'Table'[Date] ),
DAY
)
The result will then look like this (represented in a table visual):

Daily Table out of Start and End Date

I'm trying to create a calculated table with daily information of employees based on MIN and MAX dates. I'm on Power BI.
This won't be super-efficient if you have too many employees and dates, but you can take the cartesian product of the list of employees with the list of all possible days and filter that down:
CalculatedTable =
VAR CartesianProduct =
CROSSJOIN (
VALUES ( Main[employee_number] ),
CALENDAR ( MIN ( Main[start] ), MAX ( Main[end] ) )
)
RETURN
FILTER (
CartesianProduct,
[Date] >= LOOKUPVALUE ( Main[start], Main[employee_number], [employee_number] ) &&
[Date] <= LOOKUPVALUE ( Main[end], Main[employee_number], [employee_number] )
)
The CALENDAR function generates a table with column Date starting from the first argument and includes all days up to the second argument.
I'm not sure how to do this more efficiently in DAX, but I can think of a cleaner solution in M (query editor language).

DAX moving average not working

I try to calculate moving average in DAX power bi. I use different codes, for example this.
Moving AverageX 7B Days =
AVERAGEX (
DATESINPERIOD(
sahkoInput[Date];
LASTDATE ( sahkoInput[Date]);
-7;
DAY
);
sahkoInput[price]
)
All codes give the same result - Moving AverageX 7B Days is equal to column "price". What went wrong and how to fix it?
Firstly, I would look to add a date/calendar table to your data model.
This can be as simple as a list of consecutive dates from at least seven days before your first data point until after the end of when you expect your last one to be.
The reason for this is that the date functions in DAX always work best when they have a table of consecutive dates to look at - you can get unpredictable results when your fact table doesn't have any data on a particular date.
Once you have added the date table, create a relationship to link the date column in your sahkoInput table to the date column in your date table.
Now, the following measure should work:
Moving AverageX 7B Days =
CALCULATE (
AVERAGE('sahkoInput'[Price]);
DATESINPERIOD ('DateTable'[Date];
LASTDATE ('DateTable'[Date]);
-7;
DAY)
)
Create a date table, this will dramatically improve performance and increase readability. You can do that by using the following DAX:
Min Date := MIN('sahkoInput'[Date])
Max Date := MAX('sahkoInput'[Date])
Dates :=
VAR BaseCalendar =
CALENDAR ( [Min Date], [Max date] )
RETURN
GENERATE (
BaseCalendar,
VAR BaseDate = [Date]
VAR YearDate =
YEAR ( BaseDate )
VAR MonthNumber =
MONTH ( BaseDate )
RETURN
ROW (
"Day", BaseDate,
"Year", YearDate,
"Month Number", MonthNumber,
"Month", FORMAT ( BaseDate, "mmmm" ),
"Year Month", FORMAT ( BaseDate, "mmm yy" )
)
)
Then referencing this date table you can create an average using the standard average function, like so:
Moving Average 7 Days :=
CALCULATE (
AVERAGE ( 'sahkoInput'[Price] );
KEEPFILTERS ( DATESINPERIOD ( 'Dates'[Date]; MAX ( 'Dates'[Date] ); -7; DAY ) )
)
I hope this helps!