I have a table called Payment_Methods in PBI with the following columns:
timestamp, weekDay, Hour, eventType, SuccessEvents, FailedEvents, addPymntCardInstance.
weekDay is ['Sunday', 'Monday', ..., 'Friday', 'Saturday']
Hour is [0, 1, 2, 3, ..., 21, 22, 23]
I want to create a PymntSuccessRate using the DAX expression below, but the results are always the same all the way down across the column PymntSuccessRate. How can I fix this. Appreciate if you can give me some clue. Thanks.
PymntSuccessRate =
DIVIDE(
SUMX(
FILTER(
GROUPBY(
Payment_Methods,
Payment_Methods[timestamp], Payment_Methods[weekDay], Payment_Methods[Hour]
),
Payment_Methods[eventType] = "Success"
),
SUM( Payment_Methods[addPymntCardInstance] )
),
SUMX(
GROUPBY(
Payment_Methods,
Payment_Methods[timestamp], Payment_Methods[weekDay], Payment_Methods[Hour]
),
SUM( Payment_Methods[addPymntCardInstance] )
)
)
timestamp
weekDay
Hour
SuccessEvents
FailedEvents
SuccessRate
2023-01-20
Friday
20
2
8
0.20
2023-01-20
Friday
19
121
111
0.52
2023-01-17
Tuesday
6
31
8
0.79
2023-01-17
Tuesday
5
19
14
0.57
based on your sample you don't need to use SUMX and GROUPBY (visual will do the grouping), this should be enough (used as a measure, NOT a calculated column):
PymntSuccessRate =
DIVIDE (
CALCULATE (
SUM ( Payment_Methods[addPymntCardInstance] ),
Payment_Methods[eventType] = "Success"
),
SUM ( Payment_Methods[addPymntCardInstance] )
)
Related
I have 2 measures, where depending on the date filters selected, I show:
Last 12 months:
CALCULATE
(
[Xyz] , DATESINPERIOD ( 'Date'[Date] , MAX('Date'[Date]) , -12 , MONTH )
)
I need to do the same, but for months -12 to -24.
I have tried, but DATEADD doesn’t seem to work with MAX…
var dat = MAX('Date'[Date])
RETURN
CALCULATE
(
[Xyz] ,
DATESINPERIOD(
'Date'[Date],
DATEADD(dat,-12,MONTH) ,-24,MONTH)
)
How can I make the period from -12 to -24 ?
What if you try this ????? Even If I haven't tested it yet. I know you can nest Time Intelligence Functions.
_12_24 Period =
CALCULATE (
[Xyz],
SAMEPERIODLASTYEAR (
DATESINPERIOD ( 'Date'[Date], MAX ( 'Date'[Date] ), -12, MONTH )
)
)
So I am building a report that shows the time spent on a job and the income the job has generated. My boss wants to see the average income of a job in hours.
Let's say three jobs have been completed:
Job A: Time: 12 minutes & income 450 euro
Job B: Time: 24 minutes & income 600 euro
Job C: Time: 38 minutes & income 950 euro
Job D: Time: 82 minutes & income 1800 euro
How do i calculate the average income per hour in PowerBI/DAX?
If you want to do it in a structured way:
DEFINE
TABLE Payroll = SELECTCOLUMNS ({
("Job-A",FORMAT(TIME(00,12,00),"HH:MM:SS"),450),
("Job-B",FORMAT(TIME(00,24,00),"HH:MM:SS"),600),
("Job-C",FORMAT(TIME(00,38,00),"HH:MM:SS"),950),
("Job-D",FORMAT(TIME(00,82,00),"HH:MM:SS"),1800)
},"Type",[Value1],"Duration",[Value2],"Income",[Value3])
EVALUATE
Payroll
Final Code:
EVALUATE
ROW (
"AVG_Earnings",
FORMAT (
ROUND (
AVERAGEX (
ADDCOLUMNS (
ADDCOLUMNS (
Payroll,
"Hour", HOUR ( Payroll[Duration] ),
"Minute", MINUTE ( Payroll[Duration] ),
"Seconds", SECOND ( Payroll[Duration] )
),
"Total",
ROUND ( [Hour] + DIVIDE ( [Minute], 60 ) + DIVIDE ( [Seconds], 3600 ), 4 )
),
DIVIDE ( [Income], [Total] )
),
2
),
"Currency",
"de-DE"
)
)
I have a requirement in Power bi that i need to display the last month mtd on basis of selection of date slicer.
here is the details
Ex: jan 1 2020 : 10 cases, jan 2, 2020 : 30 cases.. when i select feb 2 2020 in slicer it should display the jan 2 2020 value not mtd of that month(january)
Thanks,
Imran
Without using time intelligence functions, you can probably write something like this:
LastMonthMTD =
VAR DateSelected = SELECTEDVALUE ( 'Calendar'[Date] )
VAR PrevMonth = EOMONTH ( DateSelected, -1 )
VAR PrevDate = DATE ( YEAR ( PrevMonth ), MONTH ( PrevMonth ), DAY ( DateSelected ) )
VAR StartDate = EOMONTH ( DateSelected, -2 )
RETURN
CALCULATE (
[Sum_Covid_Cases],
'Calendar'[Date] > StartDate,
'Calendar'[Date] <= PrevDate
)
Using time intelligence, you could try something like this:
LastMonthMTD =
CALCULATE (
[Sum_Covid_Cases],
DATEADD ( DATESMTD ( 'Calendar'[Date] ), -1, MONTH )
)
I haven't tested these, so let me know if they work or not.
I have 2 tables, AvailabilitiesDB and AvailabilityTemplateDB.
The AvailabilitiesDB table looks like like
IsAvailable StartTime FinishTime Employee_ID Week Day Of the Week
1 25-09-2020 16:00:00 25-09-2020 19:00:00 101 39 5
0 27-08-2020 14:00:00 27-08-2020 17:00:00 13 35 4
1 25-11-2020 09:00:00 25-11-2020 18:00:00 66 48 3
The AvailabilityTemplateDB table looks like this:
Day Of The Week StartTime FinishTime Employee_ID
3 18:00:00 21:00:00 101
2 11:00:00 17:00:00 13
6 06:00:00 20:00:00 66
Here is the issue:
I want to calculate the availability of the employees, meaning their minutes available (so from StartTime to FinishTime).
However, the thing is: The employees all have a template (AvailabilityTemplateDB) which is their go-to work schedule, so if there is not any observations in AvailabilitiesDB, it means that they use their template. But if there is an observation for a specific employee in the AvailabilitiesDB, it means that the template has been overwritten for the specific day. The templates are recurrent every week, which is why they don't have specific dates, and just "Day of the Week".
So I want to calculate something along the lines of: calculate DatesBetween (Minutes), where employee id = employee id, and if there is a data in the availabilitiesDB it must use this number, so for the first observation it would be 180 minutes, but if there is not a date in there, it must take the time from the template table. I find this hard because all I have is "Day of the week" in the template table, and I don't know how i would "convert" it to dates.
This was what I have tried (Not near end result) and obviously it's not supposed to count rows, I was just trying in order to come closer to an answer. Date refers to my date table, which holds unique dates for all of the dates from the AvailabiltiesDB table.
Try =
VAR dates =
DATESBETWEEN (
'Date'[Date].[Date],
MIN ( 'Date'[Date].[Date] ),
MAX ( 'Date'[Date].[Date] )
)
VAR Employee_ID = AvailabilitiesDB[Employee_ID]
VAR Weekdays = AvailabilitiesDB[Day Of the Week]
VAR weekdaysAndDateMatch =
VAR COUNTZ =
CALCULATE (
COUNTROWS ( AvailabilitiesDB ),
FILTER (
AvailabilityTemplateDB,
Weekdays = AvailabilityTemplateDB[Day of the week]
&& Employee_ID = AvailabilityTemplateDB[Employee_ID]))
RETURN IF ( COUNTZ = 0, "Yes", "No" )
My desired outcome would be a column in the AvailabilitiesDB table that summed the availability in minutes per week, for every employee_ID.
I hope you can help me further, thank you in advance.
Events with a duration are simplified by implementing a snapshot table.
Another good practice when dealing with time is to split the date part and the time part in two different columns
So I created a small model with dimension Date, Employees and Time
For this example we just need the months from August to November. To match the Day of the week with the sample data I had to subtract 1.
Date =
ADDCOLUMNS (
CALENDAR ( "2020-08-01", "2020-11-30" ),
"WeekDay", WEEKDAY ( [Date] ) - 1
)
The Employees dimension is
Employees =
ADDCOLUMNS (
DISTINCT ( AvailabilitiesTemplateDB[Employee_ID] ),
"Name", FORMAT ( [Employee_ID], "000" )
)
For the time dimension I created a measure as a parameter with the time granularity to be used also for the snapshot table. This can be changed to adapt the model to the requirements.
To keep a low number of lines for this example I used a 1 hour interval
TimeInterval = VALUE( "01:00:00" )
So the Time table becomes
Time =
SELECTCOLUMNS (
GENERATESERIES ( VALUE ( "00:00:00" ), VALUE ( "23:59:59" ), [TimeInterval] ),
"Time", [Value]
)
The snapshot table is a table containing a row per each time interval for which an employee is available. To build this table we can use the set functions UNION and EXCEPT. The snapshot table has just three columns: the Employee_ID, the Date and the Time
This code matches the Date with the weekday using the Date table we build before
AvailabilitiesSnapshot =
VAR TimeGranularity = [TimeInterval]
VAR AvailableFromTemplateDB =
SELECTCOLUMNS(
GENERATE(
AvailabilitiesTemplateDB,
VAR DayOfWeek = AvailabilitiesTemplateDB[Day Of The Week]
VAR TimesTable =
SELECTCOLUMNS(
GENERATESERIES(
AvailabilitiesTemplateDB[StartTime],
AvailabilitiesTemplateDB[FinishTime] - TimeGranularity,
TimeGranularity
),
"Time", [Value]
)
RETURN
GENERATE(
FILTER( ALLNOBLANKROW( 'Date' ), 'Date'[WeekDay] = DayOfWeek ),
TimesTable
)
),
"Employee_ID", [Employee_ID],
"Date", [Date],
"Time", [Time]
)
VAR AvailableFromDB =
SELECTCOLUMNS(
GENERATE(
CALCULATETABLE( AvailabilitiesDB, AvailabilitiesDB[IsAvailable] = 1 ),
VAR TimesTable =
SELECTCOLUMNS(
GENERATESERIES(
AvailabilitiesDB[StartTimeOnly],
AvailabilitiesDB[FinishTimeOnly] - TimeGranularity,
TimeGranularity
),
"Time", [Value]
)
RETURN
TimesTable
),
"Employee_ID", [Employee_ID],
"Date", [Date],
"Time", [Time]
)
VAR UnavailableFromDB =
SELECTCOLUMNS(
GENERATE(
CALCULATETABLE( AvailabilitiesDB, AvailabilitiesDB[IsAvailable] = 0 ),
VAR TimesTable =
SELECTCOLUMNS(
GENERATESERIES(
AvailabilitiesDB[StartTimeOnly],
AvailabilitiesDB[FinishTimeOnly] - TimeGranularity,
TimeGranularity
),
"Time", [Value]
)
RETURN
TimesTable
),
"Employee_ID", [Employee_ID],
"Date", [Date],
"Time", [Time]
)
RETURN
EXCEPT(
DISTINCT( UNION( AvailableFromTemplateDB, AvailableFromDB ) ),
UnavailableFromDB
)
In this code first we add all available intervals, then we remove the intervals that are marked as not available, those with AvailabilitiesDB[IsAvailable] = 0
Then we create the relationships between this new snapshot table and the dimensions, to get the model
with this model, writing a measure to compute the available minutes is straigthforward
AvailableTime = COUNTROWS( AvailabilitiesSnapshot ) * [TimeInterval] * 24 * 60
The TimeInterval parameter can be changed to rise the detail level. Of course this will increase the number of rows of the snapshot table and also depends on the size of the input tables.
While building a calendar table I came across unexpected hard nut to crack.
How to convert date to the first date of the quarter? Here are some examples:
2019-02-01 > 2019-01-01
2019-03-31 > 2019-01-01
2019-04-02 > 2019-04-01
The function STARTOFQUARTER does not work in my calendar. I do not know why.
Calendar =
GENERATE (
CALENDAR (
DATE ( 2016, 1, 1 ),
DATE ( 2020, 12, 31 )
),
VAR VarDates = [Date]
var YQ_date = STARTOFQUARTER( [Date] ) -- this does not work
RETURN
ROW (
"day" , VarDay,
"YQ_date" , YQ_date
)
)
The only option seems to be adding calculated column to Calendar table. But if it is possible to have it straight, then why not have it straight?
How about as an added column?
Calendar =
ADDCOLUMNS (
CALENDAR ( DATE ( 2016, 1, 1 ), DATE ( 2020, 12, 31 ) ),
"YQ_date", EOMONTH ( [Date], -1 - MOD ( MONTH ( [Date] ) - 1, 3 ) ) + 1
)
For the STARTOFQUARTER function to work, you need the dates that you expect to be returned by the function in your datetable.
So in the provided sample, you need to add the dates 2019-01-01 and 2019-04-01.
Something like this:
When you want to build a calendar table with one DAX expression, you cannot use the STARTOFQUARTER function, because it will not work with an in-memory table.
You could use something like this as a workaround though:
Calendar =
GENERATE (
CALENDAR (
DATE ( 2016; 1; 1 );
DATE ( 2020; 12; 31 )
);
ROW (
"YQ_date"; DATE( Year( [Date] ); ROUNDUP( MONTH ( [Date] ) / 3; 0 ) * 3 - 2; 1)
)
)