I'm trying to imitate this report (page 3) where it slices active headcount and all the other metrics (1) by date and (2) by department.
My data looks like this (with relationships, of course):
ID
Name
DEPID
Hired Date
Terminated Date
Terminated (Y/N)
1
John
2
1/1/2019
2020/12/31
Y
2
Jane
2
1/3/2018
2019/07/26
Y
3
Jack
1
1/5/2022
null
N
Using the following measure, I was able to extract total number of employees by date, but I wasn't able to filter by department:
CountOfActive =
var _selectedDate = MAX('Calendar'[Date])
return
CALCULATE(COUNTROWS('Table'); filter(ALL('Table'); Table[HIREDDATE] <= VALUE(_selectedDate) && (Table[TERMINATEDDATE] >= VALUE(_selectedDate) || ISBLANK(Table[TERMINATEDDATE]))))
My ideal output is something like the following (where I'll create a table for each department and list the number of active employees, then join them to my department key table afterwards so I can slice them):
Date
Count of Active Employees
Department
2019/1/1
3
Retail
2019/1/2
3
Retail
2019/1/3
4
Retail
...
...
...
The "Date" column would be a calendar table built with CALENDAR().
What should I do to achieve the last table based on the data I have?
My relationship schema looks like this.
try this : 'Table 2' is your Calendar Table which is also a slicer on the visual.
Make sure that your Calendar Table's Date has a relation with the Hired Date and also the relation between the Department Table
Count of Emp =
VAR _latest =
MAX ( 'Table 2'[Date] )
VAR _from =
MIN ( 'Table 2'[Date] )
VAR _dept =
SELECTEDVALUE ( Department[Department] )
RETURN
CALCULATE (
COUNTX ( 'Table', 'Table'[ID ] ),
FILTER (
ALL ( 'Table' ),
'Table'[Terminated Date ] >= _from
&& 'Table'[Hired Date ] <= _from
&& 'Table'[Terminated (Y/N)] = "Y"
&& RELATED ( Department[Department] ) = _dept
)
)
+ CALCULATE (
COUNTX ( 'Table', 'Table'[ID ] ),
FILTER (
ALL ( 'Table' ),
'Table'[Terminated (Y/N)] = "N"
&& 'Table'[Hired Date ] <= _from
&& RELATED ( Department[Department] ) = _dept
)
)
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 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 )
)
I have the following values in Table_1:
date sales_amount
04/01/2021 100.00
04/02/2021 300.00
04/05/2021 500.00
I want to compute a running average, so the average is computed as each day passes, so that my final output looks like this:
date sales_amount running_average
04/01/2021 100.00 100.00
04/02/2021 300.00 200.00
04/05/2021 500.00 300.00
The sales person did not work on 04/03 and 04/04, so I want to exclude them from my running average.
Right now, my output looks like this, which is wrong for what I am doing:
date sales_amount running_average
04/01/2021 100.00 100.00
04/02/2021 300.00 200.00
04/05/2021 500.00 180.00
Any suggestions?
Right now, my DAX code looks like this:
test_new =
VAR LastVisibleDate = MAX('Table_1'[Date])
VAR FirstVisibleDate = MIN('Table_1'[Date])
VAR LastDateWithSales =
CALCULATE(
MAX('Table_1'[Date]),
REMOVEFILTERS()
)
VAR Result =
IF (
FirstVisibleDate <= LastDateWithSales,
CALCULATE(
AVERAGE([Sales_Amount]),
Table_1[Date]
)
)
RETURN
Result
I have added a few lines in the last variable:
Table_1[Date] in the last variable basically means FILTER ( ALL ( Table_1[Date] ), TRUE ), and that will return all of the dates so not useful in your scenario as it will give wrong results, instead write Table_1[Date] <= LastVisibleDate
You don't need REMOVEFILTERS when you have Date column coming from the Dates table and the Date table is marked as a Date table because when a date table is marked as a date table the engine automatically adds a REMOVEFILTERS/ALL whenever a filter is applied over the Date column, but that won't happen with Date column of other tables hence you need to write an explicit REMOVEFILTERS in the last variable
test_new =
VAR LastVisibleDate =
MAX ( 'Table_1'[Date] )
VAR FirstVisibleDate =
MIN ( 'Table_1'[Date] )
VAR LastDateWithSales =
CALCULATE (
MAX ( 'Table_1'[Date] ),
REMOVEFILTERS ()
)
VAR Result =
IF (
FirstVisibleDate <= LastDateWithSales,
CALCULATE (
AVERAGE ( [Sales_Amount] ),
Table_1[Date] <= LastVisibleDate,
REMOVEFILTERS ( Table_1 )
)
)
RETURN
Result
As a best practice always use Date column from a Date table.
I am trying to do the cumulative count for the users first time access the web page.
Table looks like,
UserID , Initial Access Date
100, 2019-05-10
200, 2019-05-20
100, 2019-05-21
100, 2019-05-25
200, 2019-05-30
300, 2019-06-01
Current Expression:
Cumulative Total =
CALCULATE (
DISTINCTCOUNT ( [USERID] ),
FILTER (
ALLSELECTED ( TABLE ),
[INITIAL ACCESS DATE] <= MAX ( [INITIAL ACCESS DATE] )
)
)
This only returns cumulative total count, How would I get the running total based on this count of Users.
Expected Results:
1 - Upload your Fact table in Power Bi
2 - Create a Date Table
Date = CALENDARAUTO()
Then
Year = Year('Date'[Date])
Month = MONTH('Date'[Date])
YEAR_MONTH = VALUE('Date'[Year])*100+VALUE('Date'[Month])
3 - Set relationships
4 - You can compute a set of two measures :
First
InitialAccess =
VAR InitialAccessInCurrentPeriod =
DISTINCTCOUNT(Fact_T[UserID ])
RETURN
InitialAccessInCurrentPeriod
Then :
InitialAccessCumulated =
VAR MaxDateInPeriod = MAX('Date'[Date]) // Retrieve the last date in current filter context
VAR StartingDate = MINX(ALLSELECTED('Date');[Year]) // Retrieve the lowest year selected on slicer
RETURN
CALCULATE(
[InitialAccess]; // Compute the number of initial access
FILTER( // In a nex filter context where all the dates
ALL('Date'); // Equal or superior to the lowest date selected
'Date'[Year]>=StartingDate
&&
'Date'[Date]<= MaxDateInPeriod // Until the last date visible in the current row context
)
)
You can see the final result here :
I have added to row to your fact table to have several years
Here is the Fact table used :
UserID Initial Access Date
50 12/12/2018
100 10/05/2019
200 20/05/2019
100 21/05/2019
100 25/05/2019
200 30/05/2019
300 01/06/2019
400 04/02/2020
Finally I got it working without creating extra columns or measures,
Cumulative Total =
CALCULATE (
SUMX (
Table,
IF ( DISTINCTCOUNT ( Table[UserID] ) > 0, 1, 0 )
),
FILTER (
ALLSELECTED ( Table ),
Table[InitialAccessDate]
<= MAX ( Table[InitialAccessDate] )
)
)
Cheers!!
I have a scenario with two data slicers. The first data slicer filters data for one period, the second one for another period. By editing visual interactions I got this works at the same page.
Now I want to compare two resulting values (in this case, number of transactions, and find a percentage of change between two selected periods.
I duplicated data column so I have two date columns for each slicer and I calculated the next measures:
# of Transactions 1 = CALCULATE(COUNT(Report[ProductID]),DATESBETWEEN(Report[Date1],[Start Date 1],[Last Date 1]))
# of Transactions 2 = CALCULATE(COUNT(Report[ProductID]),DATESBETWEEN(Report[Date2],[Start Date 2],[Last Date 2]))
% Transaction Change = ([# of Transactions 1]/[# of Transactions 2]) - 1
The first 2 measures are accurate (# of Transactions 1 & 2), but % of change doesn't work.
If you look at the screenshot below, you'll see # od Transactions 1 = 1,990 and # of Transactions 2 = 2,787. I want to compare this 2 values now.
How can I solve this?
Thank you.
First create two measure for your date bounds:
Min Date :=
MIN ( 'Report'[Date] )
Max Date :=
MAX ( 'Report'[Date] )
Then create a date table using the following DAX, this will join to you 'Report' table on the primary date:
Dates :=
VAR MinDate = [Min Date]
VAR MaxDate = [Max Date]
VAR BaseCalendar =
CALENDAR ( MinDate, MaxDate )
RETURN
GENERATE (
BaseCalendar,
VAR BaseDate = [Date]
VAR YearDate =
YEAR ( BaseDate )
VAR MonthNumber =
MONTH ( BaseDate )
VAR YrMonth =
100 * YEAR ( BaseDate )
+ MONTH ( BaseDate )
VAR Qtr =
CONCATENATE ( "Q", CEILING ( MONTH ( BaseDate ) / 3, 1 ) )
VAR YrMonthQtr =
100 * YEAR ( BaseDate )
+ MONTH ( BaseDate )
& CONCATENATE ( "Q", CEILING ( MONTH ( BaseDate ) / 3, 1 ) )
VAR YrMonthQtrDay =
100 * YEAR ( BaseDate )
+ MONTH ( BaseDate )
& CONCATENATE ( "Q", CEILING ( MONTH ( BaseDate ) / 3, 1 ) )
& DAY ( BaseDate )
RETURN
ROW (
"Day", BaseDate,
"Year", YearDate,
"Month Number", MonthNumber,
"Month", FORMAT ( BaseDate, "mmmm" ),
"Year Month", FORMAT ( BaseDate, "mmm yy" ),
"YrMonth", YrMonth,
"Qtr", Qtr,
"YrMonthQtr", YrMonthQtr,
"YrMonthQtrday", YrMonthQtrDay
)
)
Now create another date table from which to compare, and join to your primary date table in 'Report' and ensure the relationship is inactive:
Compare Dates :=
ALLNOBLANKROW ( 'Dates' )
Now create the [# of transaction] measure; one for 'Dates' and another for 'Compare Dates' like so:
[# of Transaction 1] :=
CALCULATE (
COUNT ( Report[ProductID] )
)
[# of Transaction 2] :=
CALCULATE (
[# of transaction 1],
ALL ( 'Dates' ),
USERELATIONSHIP ( 'Compare Dates'[Date], 'Report'[Date] )
)
Now Create the % Delta measure:
Transaction Change := CALCULATE(DIVIDE([# of Transactions 1],[# of Transactions 2]) - 1)
This should work like a charm and will work for any dates selected in your slicers, you will still need to associate your date slicers with your new date tables.
I hope this helps!!