Well, this problem is hard to explain, but here we go.
Consider this a tab with the following columns:
ID,
TITLE,
PHASE,
START_DATE, ( id enters the phase)
END_DATE, (id leaves the phase)
I want to calculate the difference between start and end date, this would be quite simple but...
I need to calculate the difference between the START_DATE of the phase "PROSPECT" and the START_DATE of "GAIN" phase.
And it needs to be calculated ONLY for the ID's that started in the "PROSPECT" phase until "GAIN" phase.
Any other ID needs to be kept out of this measure.
Explaining what I want:
The ID's are clients, I want to calculate how long it takes for our clients who enters as a prospect to reach the gain phase, which means, become our client.
Thank-you in advance.
I did the same question in PBI Community: https://community.powerbi.com/t5/Desktop/Calculate-date-difference-between-two-specific-categories/m-p/3068863#M1041877
You need something like this, where you calculate the start dates for the two phases of interest, but retain a filter on the selected ID:
Diff =
VAR _prospect =
CALCULATE (
MAX ( 'Table'[START_DATE] ) ,
ALLEXCEPT (
'Table' ,
'Table'[ID]
) ,
'Table'[PHASE] = "PROSPECT"
)
VAR _gain =
CALCULATE (
MAX ( 'Table'[START_DATE] ) ,
ALLEXCEPT (
'Table' ,
'Table'[ID]
) ,
'Table'[PHASE] = "GAIN"
)
RETURN
IF (
HASONEVALUE ( 'Table'[ID] )
&& _prospect <> BLANK ()
&& _gain <> BLANK () ,
DATEDIFF ( _prospect , _gain , DAY )
)
Here I also remove any cases where either _prospect or _gain are evaluated to be blank for the given ID. I also short-circuit the calculation if there are more than 1 IDs present.
If you want the average for your IDs then you can look at a measure like this, using the same measure in an iterator:
Avg Diff =
AVERAGEX (
VALUES ( 'Table'[ID] ) ,
[Diff]
)
Related
I am trying to use a calculate statement with a measure to filter results of a table but I need the values to change if the user selects 1 date from a slicer. Below is the code I am using.
PCurrentDay = calculate(sum('Sheet0 (2)'[Toys_Count]),datediff('Sheet0 (2)'[SCAN_Date],'Sheet0 (2)'[SHIP_Date],DAY)=0)
This returns a value but it won't update if the user selects a specific scan date. Any ideas?
Can you replace the measure with following
Measure =
CALCULATE (
SUM ( 'Table'[val] ),
FILTER (
'Table',
DATEDIFF (
CALCULATE ( MAX ( 'Table'[scan] ) ),
CALCULATE ( MAX ( 'Table'[ship] ) ),
DAY
) = 0
)
)
CALCULATE inside DATEDIFF provides the correct context for the filter to work.
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):
I'm struggling to write/calculate this measure in DAX. The definition of recall rate is count of repeat service bookings (count of distinct booking number, should be distinct anyway but just in case) for a customer, asset combination within a week (Closed on date, 7 day period). So I go out to fix a machine, if I get called out again to fix the same machine for the customer within a week that is then a recall of 1 (or more if i get called out multiple times within a week). I've highlighted the groups in different colours. Null Assets, Closed On and null booking number needs to be filtered out (this is done by inner join in SQL in below code, needs to be in DAX query) Thanks! EDIT : Sorry realised it would be more helpful if I posted sql code to generate data please see below :
SELECT
FB.BookingNumber,
FB.EngineerEmployeeID,
FWO.ServiceAccountRecID AS Customer,
FWO.AssetRecID AS Asset,
FWO.ClosedOn
FROM dbo.FactWorkOrder AS FWO JOIN dbo.FactBooking AS FB ON FB.WorkOrderID = FWO.WorkOrderID
WHERE FWO.WorkOrderType = 'Breakdown'
AND AssetRecID IS NOT NULL
AND ClosedOn IS NOT NULL
ORDER BY BookingNumber
It's most efficient if you first define a calculated column that gives the first CloseOn date for each Customer/Asset combination.
FirstClosed =
CALCULATE (
MIN ( WorkOrder[ClosedOn] ),
ALLEXCEPT ( WorkOrder, WorkOrder[Customer], WorkOrder[Asset] )
)
and then write a measure
TotalRecalls =
COUNTROWS (
FILTER (
WorkOrder,
WorkOrder[ClosedOn] > WorkOrder[FirstClosed] &&
WorkOrder[ClosedOn] < WorkOrder[FirstClosed] + 7
)
)
However, you can do this all within a single measure if you prefer.
TotalRecalls =
VAR AddCol =
ADDCOLUMNS (
WorkOrder,
"#FirstClosed",
CALCULATE (
MIN ( WorkOrder[ClosedOn] ),
ALLEXCEPT ( WorkOrder, WorkOrder[Customer], WorkOrder[Asset] )
)
)
RETURN
COUNTROWS (
FILTER (
AddCol,
WorkOrder[ClosedOn] > [#FirstClosed] &&
WorkOrder[ClosedOn] < [#FirstClosed] + 7
)
)
Either way, here's what this looks like used in a visual:
I would first create a "Booking Key" column:
Booking Key = [Customer] & "|" & [Asset] & "|" & WEEKNUM ( [ClosedOn] )
Then I would create a Measure to return a modified distinct count on the Booking Key:
# Repeat Service Bookings =
VAR v_Count = DISTINCTCOUNT ( 'Table'[Booking Key] )
RETURN IF ( v_Count > 1, v_Count - 1 )
I would add # Repeat Service Bookings to the Visual Level Filters of your table visual, with the filter set to: is greater than 1.
I'm hoping someone can help as I've completely run out of ideas.
I'm working on performance reporting data, producing a number of visuals to summarise the most recent data. To allow users to retrospectively produce reports from previous quarters, I have added a date slicer as a way to "View data as at xxxx date".
Here's a rough representation of my data table - the due dates are in English format (dd/mm/yyyy):
The ratings are calculated in another system (based on a set of targets), so there are no calculated columns here. In reality, there are a lot more measures that report on different time periods (some weekly, some annually, etc) and there are different lags before the data is "due".
I eventually managed to get a measure that returned the latest actual:
MostRecentActual =
VAR SlicerDate = MAX ( Dates[Day] )
RETURN
CALCULATE (
SUM ( Data[Actual] ),
Data[Data due] <= SlicerDate,
LASTDATE ( Data[Data due] )
)
I'm not completely sure I've done it right but it seems to work. I'd be happier if I understood it properly, so explanations or alternatives would be welcomed.
What I'm trying to do now is a basic summary pie chart at the beginning which shows the proportion of the measures that were red, amber, green or unrated as at the date selected. So I would need it to count the number of each rating, but only one for each measure and only for the date that is closest to (but before) the slicer date, which would vary depending on the measure. So using the above three measures, if the slicer was set to 10/10/2019 (English format - dd/mm/yyyy), it would count the RAGs for Q3 2019/20 for measures A an C and for Q2 2019/20 for measure B as there is a time lag which means the data isn't ready until the end of the month. Results:- A: Amber, B: Green, C:Red.
If I were able to create the measure that counted these RAGs, I would then want to add it to a pie chart, with a legend that is "Rating", so it would split the chart up appropriately. I currently can't seem to be able to do that without it counting all dates before the slicer (not just the most recent) or somehow missing ratings from the total for reasons I don't understand.
Any help would be very gratefully received.
Many thanks
Ben
Further update. I've been working on this for a while!
I have created a COUNTAX measure to try to do what I was wanting to do. In some circumstances, it works, but not all and not in the crucial ones. My measure is:
TestCountaxpt2 =
VAR SlicerDate = MAX ( Dates[Date] )
VAR MinDiff =
MINX (
FILTER (
ALL ( Data ),
Data[Ref] IN VALUES ( Data[Ref] ) &&
Data[Data due] <= SlicerDate
),
ABS ( SlicerDate - Data[Data due] )
)
VAR thisdate =
MINX (
FILTER (
ALL ( Data ),
Data[Ref] IN VALUES ( Data[Ref] ) &&
ABS ( SlicerDate - Data[Data due] ) = MinDiff
),
Data[Data due]
)
RETURN
COUNTAX (
FILTER ( Data, Data[Data due] = thisdate && Data[Ref] IN VALUES ( Data[Ref] ) ),
Data[RAG]
)
It produces the following table for a subset of the performance measures, which looks almost ok:
Table showing the result of the TestCountaxpt2 measure:
The third column is the measure above and it seems to be counting one RAG per measure and the dates look correct as the slicer is set to 3rd January 2020. The total for column 3 confuses me. I don't know what that is counting and I don't understand why it doesn't add up to 7.
If I add in the RAG column from the data table, it goes a bit more wrong:
Same table but with RAG Rating added:
The pie chart that is produced is also wrong. It should show 2 Green, 2 Red, 2 Grey (no rating) and 1 Amber. This is what happens.......
Pie chart for the DAX measure, with RAG Rating in the legend:
I can see what it is doing, which is to work out the most recent due date to the slicer in the whole table and using that (which is 1st Jan 2020) whereas I want it to calculate this separately for each measure.
Link to PBIX:
https://drive.google.com/file/d/1RTokOjAUADGHNXvZcnCCSS3Dskgc_4Cc/view?usp=sharing
Reworking the formula to count the ratings:
RAGCount =
VAR SlicerDate =
MAX ( Dates[Day] )
RETURN
COUNTAX (
ADDCOLUMNS (
SUMMARIZE (
FILTER ( Data, Data[Data due] <= SlicerDate ),
Data[Ref],
"LastDateDue", LASTDATE ( Data[Data due] )
),
"CountRAG", CALCULATE (
COUNTA ( Data[RAG] ),
Data[Data due] = EARLIER ( [LastDateDue] )
)
),
[CountRAG]
)
Here's the table it produces:
The reason for Total = 4 for the third column is straightforward. The SelectDate is maximal over all of the Refs in the table and there are only four Refs that match that date.
To fix this and get the totals you're after, you'll need to iterate over each Ref and calculate the SlicerDate for each independently and only then do your lookups or sums.
I haven't tested this code but it should give you an idea of a direction to try:
MostRecentActual =
VAR SlicerDate = MAX ( Dates[Day] )
RETURN
SUMX (
ADDCOLUMNS (
SUMMARIZE (
FILTER ( Data, Data[Data due] <= SlicerDate ),
Data[Ref],
"LastDateDue", LASTDATE ( Data[Data due] )
),
"SumActual", CALCULATE (
SUM ( Data[Actual] ),
Data[Data due] = EARLIER ( [LastDateDue] )
)
),
[SumActual]
)
Going inside to outside,
FILTER the table to ignore any dates beyond the SlicerDate.
Calculate the LastDateDue for each Ref using SUMMARIZE.
Sum the Actual column for each Ref value using its specific LastDateDue.
Iterate over this summary table to add up SumActual across all Refs in the current scope.
Note that for 4, only the Total row in your visual will contain multiple Refs since the innermost Data table inside FILTER is not the entire Data table but only the piece visible in the local filter context.
Story:
I have two date columns in my fact table, one is for orderdate and the second is for orderdate/refund/cancelled date.
I created two relationships between the date table and the fact table.
Active: Date > OrderDate
Inactive: Date > OtherDate
I would like to sum the # of refunds per day using the inactive relationship.
What I tried:
Returns =
VAR summary =
SUMMARIZE (
FILTER ( Query1, Query1[kind] = "refund" ),
Query1[orderId],
"returns", MAX ( Query1[amount] )
)
RETURN
CALCULATE (
MAX ( Query1[amount] ),
USERELATIONSHIP ( Query1[OtherDate], DateTable[Date] ),
summary
)
For some reason, it's using the active date column. Any suggestion on how to fix the above formula?
I'm not sure I understand how you are intending to use the summary variable here, but note that USERELATIONSHIP doesn't affect it at all since it's already computed.
You might not need that variable at all. Try this:
Returns =
CALCULATE (
MAX ( Query1[amount] ),
USERELATIONSHIP ( Query1[OtherDate], DateTable[Date] ),
Query1[kind] = "refund"
)