How to do if with multiple rows in PowerBi? - powerbi

I have two tables like this
Table: creation date
ID user create date
1 ABC Jan 1, 2021
2 EFC Feb 1, 2021
3 HIJ Feb 1, 2021
1 ABC Feb 1, 2021
1 ABC Feb 20, 2021
And a log of blocking
ID user blocked from blocked till
1 ABC Jan 20, 2021 Feb 10, 2021
3 HIJ Jan 5, 2021 Jan 10, 2021
1 ABC Feb 25, 2021 Mar 10, 2021
As you can see the relationship between the tables are Many to Many. What I wanted to check is if the create date is during the blocked date in the log.
If it was ONE to MANY relationship, I could have used
Yes or No = IF(AND(creation date < RELATED(log[blocked from]), creation date > RELATED(log[blocked till])), "Yes", "No")
But now as there are multiple rows for the same ID how can I just check if the creation date is between any of the blocked from and Blocked till date?

You can use a measure like this
Measure2 =
VAR _maxID =
MAX ( creationDate[ID] )
VAR _minBlockedFrom =
CALCULATE (
MIN ( blockLog[blocked from] ),
FILTER ( VALUES ( blockLog[ID] ), blockLog[ID] = _maxID )
)
VAR _maxBlockedTill =
CALCULATE (
MAX ( blockLog[blocked till] ),
FILTER ( VALUES ( blockLog[ID] ), blockLog[ID] = _maxID )
)
VAR _maxDate =
MAX ( creationDate[create date] )
RETURN
IF ( _maxDate >= _minBlockedFrom && _maxDate <= _maxBlockedTill, "Yes", "No" )
Edit
please use a measure like this
Measure3 =
MAXX (
ADDCOLUMNS (
FILTER (
CROSSJOIN (
SELECTCOLUMNS (
creationDate,
"_id", creationDate[ID],
"_user", creationDate[user],
"_date", creationDate[create date]
),
blockLog
),
[_user] = [user]
),
"condition",
IF ( [_date] >= [blocked from] && [_date] <= [blocked till], "Yes", "No" )
),
[condition]
)

You can create a Measure as below-
is_from_block_range =
var current_row_id = min('CreationDate'[ID])
var current_row_user = min('CreationDate'[user])
var creation_date = min('CreationDate'[create date])
var chk_macth =
COUNTROWS(
FILTER(
all('BlockLog'),
'BlockLog'[ID] = current_row_id
&& 'BlockLog'[user] = current_row_user
&& 'BlockLog'[blocked from] <= creation_date
&& 'BlockLog'[blocked till] >= creation_date
)
)
return if(chk_macth >=1, "Yes", "No")
Output will be as below-

Related

Count unique occurrences within a year

My database schema looks like down below
ID
Date
Status
ID1
2022/01/01
Active
ID1
2022/02/01
Active
ID1
2022/03/01
Active
ID1
2022/04/01
Terminated
ID2
2022/01/01
Active
ID2
2022/02/01
Terminated
I'd like to calculate unique occurrences from start of selected date year, till the selected date. My formula is:
CountOfUnique = CALCULATE( DISTINCTCOUNT( 'Table'[ID] ) , 'Table'[STATUS] = "Active", DATESBETWEEN('CALENDAR'[DATE], STARTOFYEAR('CALENDAR'[DATE]), MAX('CALENDAR'[DATE]) ))
In SQL I'd need something like
SELECT COUNT ( DISTINCT ID) FROM Table
WHERE STATUS = "ACTIVE"
AND DATE BETWEEN 2022/01/01 AND 2022/04/01
Try this:
CountOfUnique =
CALCULATE (
DISTINCTCOUNT ( 'Table'[ID] ),
'Table'[STATUS] = "Active",
DATESBETWEEN (
'CALENDAR'[DATE],
STARTOFYEAR ( 'CALENDAR'[DATE] ),
SELECTEDVALUE ( 'CALENDAR'[DATE] )
)
)
when you have a slicer on the visual, the start of selected date year doesnt mean much as you select the dates on the slicer. I created a Calendar Table = CALENDARAUTO() so it started from the 2022/01/01...
use one of these as you like...
sample PBix File
Unique Count =
VAR _max =
MAX ( 'Calendar Table'[Date] )
VAR _min =
MIN ( 'Calendar Table'[Date] )
RETURN
CALCULATE (
DISTINCTCOUNT ( 'Table'[ID ] ),
'Table'[Date ] <= _max
&& 'Table'[Date ] >= _min
)
or only Active if you need
Unique Count (Active) =
VAR _max =
MAX ( 'Calendar Table'[Date] )
VAR _min =
MIN ( 'Calendar Table'[Date] )
RETURN
CALCULATE (
DISTINCTCOUNT ( 'Table'[ID ] ),
'Table'[Date ] <= _max
&& 'Table'[Date ] >= _min
&& 'Table'[Status] = "Active"
)

How to Create a Slicer that uses dates and that only contains YTD Months dynamically by current date in PowerBI

Trying to create a slicer that when clicked only the months YTD, specifically up the the last month of current.
Such as slicer box clicked: (Say current month is August) then Months "Jan","Feb",..."July" would only display to click.
I've tried several things, my last attempt was to create a Dax table with dates and try to do a switch:
Dates =
var CurrentMonthInt = month(TODAY())
var monthis8 = "Jan" + "Feb" + "March" + "April" + "May" + "June" + "July"
VAR BaseTable =
CALENDAR(
DATE( YEAR ( MIN(Reporting[InvoiceDate])),01,01),
DATE( YEAR ( MAX(Reporting[InvoiceDate])),12,31)
)
RETURN
ADDCOLUMNS(
BaseTable,
"Year", YEAR([Date]),
"Month", FORMAT([Date],"mm"),
"Year Month", FORMAT([Date],"YYYY MM"),
"Month YTD", SWITCH(TRUE(),
CurrentMonthInt = 1, "Jan",
CurrentMonthInt = 8, monthis8,
"testing"
)
)
this returns a variant data type and will not work. I am thinking this is trying to add them all up on the same row.
Hello Please test this and let me know if It solves your problem.
Dates =
VAR CurrentMonthInt =
MONTH ( TODAY () )
VAR BaseTable =
CALENDAR (
DATE ( YEAR ( MIN ( Reporting[InvoiceDate] ) ), 01, 01 ),
DATE ( YEAR ( MAX ( Reporting[InvoiceDate] ) ), 12, 31 )
)
RETURN
FILTER (
ADDCOLUMNS (
BaseTable,
"Year", YEAR ( [Date] ),
"Month", MONTH ( [Date] ),
"Year Month", FORMAT ( [Date], "YYYY MM" )
),
[Month] <= CurrentMonthInt - 1
)
Note: I haven't tested it.

DAX Creating Calendar Table With Additional Field

I'm creating a calendar table in DAX:
Dates =
CALENDAR (
MIN ( 'Work Weeks'[Start Date].[Date] ),
MAX ( 'Work Weeks'[Start Date].[Date] )
)
The work weeks table contains a week number and a start date for each week.
For each date in my new Dates table, I want to assign a work week number using the start date of the work week. Note that work weeks start on different days of the week (they're assigned properly in my work weeks table though).
So what I'm trying is:
Dates =
ADDCOLUMNS (
CALENDAR (
MIN ( 'Work Weeks'[Start Date].[Date] ),
MAX ( 'Work Weeks'[Start Date].[Date] )
),
"Work Week",
CALCULATE (
MAX ( 'Work Weeks'[Start Date].[Date] ),
'Work Weeks'[Start Date] <= Date
)
)
I'm not sure how to reference the current row/date in the condition at the end. And then I also need to return the work week number, rather than just the start date.
Assuming your work week table looks something like this:
You can use this date table code to add the week number:
Date Table =
VAR ListOfDate =
VAR MinDate = MIN ( Sales[Order Date] ) -- Replace the reference with the column of your model
VAR MaxDate = MAX ( Sales[Order Date] ) -- Replace the reference with the column of your model
VAR StartDate = DATE ( 2021, 1, 1 ) -- DATE ( YEAR ( MinDate ), 1, 1 )
VAR EndDate = DATE ( 2021, 12, 31 ) -- DATE ( YEAR ( MaxDate ), 12, 31 )
VAR Result = CALENDAR ( StartDate, EndDate )
RETURN
Result
VAR WorkWeekTable = ALL ( WorkWeek )
VAR CalendarTable =
GENERATE (
ListOfDate,
VAR CurrentDate = [Date]
RETURN
ROW (
"Calendar Year Number", YEAR ( CurrentDate ),
"Calendar Month Number", MONTH ( CurrentDate ),
"Work week",
CALCULATE (
MIN ( WorkWeek[Work Week Number] ),
CurrentDate >= WorkWeek[Work Week Start Date],
CurrentDate <= WorkWeek[Work Week End Date],
REMOVEFILTERS ( )
)
)
)
RETURN
CalendarTable
The result will look like this:

Current Fiscal Week with ISO Calendar

I have implemented a fiscal calendar into my Power BI Data Model for some time intelligence magic.
This fiscal calendar has a specific start and end date for each month and is mainly based on ISO 8601 Calendar (Gregorian).
However, my current approach is not working anymore for this year, since the filter "Current Fiscal Week" is not working. If I filter on Current Fiscal Week, then I get the second week of January instead of the first week.
But why?
My code has the following structure:
Calendar =
VAR BaseCalendar =
CALENDAR (
DATE ( 2020, 1, 1 ),
DATE ( 2022, 01, 03 )
)
RETURN
GENERATE (
BaseCalendar,
VAR BaseDate = [Date]
VAR WeekNumber =
WEEKNUM ( BaseDate )
VAR Year =
YEAR ( BaseDate )
VAR FiscalWeek =
WEEKNUM (
BaseDate,
21
)
VAR FiscalYear =
IF (
FiscalWeek < 5
&& WeekNumber > 50,
Year + 1,
IF (
FiscalWeek > 50
&& WeekNumber < 5,
Year - 1,
Year
)
)
RETURN
ROW (
"Fiscal Week", FiscalWeek,
"Current Fiscal Week",
IF (
AND (
FiscalWeek
= WEEKNUM (
TODAY (),
2
),
FiscalYear
= YEAR (
TODAY ()
)
),
TRUE (),
FALSE ()
)
)
)
I think that the Current Fiscal week should be found with the same formulas used to compute the FiscalWeek and FiscalYear. I put the variable definitions for the new variables outside of the GENERATE, since they just depend on TODAY()
VAR TodayBaseDate =
TODAY()
VAR TodayWeekNumber =
WEEKNUM( TodayBaseDate )
VAR TodayYear =
YEAR( TodayBaseDate )
VAR TodayFiscalWeek =
WEEKNUM( TodayBaseDate, 21 )
VAR TodayFiscalYear =
IF(
TodayFiscalWeek < 5
&& TodayWeekNumber > 50,
TodayYear + 1,
IF( TodayFiscalWeek > 50 && TodayWeekNumber < 5, TodayYear - 1, TodayYear )
)
VAR BaseCalendar =
CALENDAR( DATE( 2020, 1, 1 ), DATE( 2022, 01, 03 ) )
RETURN
GENERATE(
BaseCalendar,
VAR BaseDate = [Date]
VAR WeekNumber =
WEEKNUM( BaseDate )
VAR Year =
YEAR( BaseDate )
VAR FiscalWeek =
WEEKNUM( BaseDate, 21 )
VAR FiscalYear =
IF(
FiscalWeek < 5
&& WeekNumber > 50,
Year + 1,
IF( FiscalWeek > 50 && WeekNumber < 5, Year - 1, Year )
)
RETURN
ROW(
"Week day", FORMAT( [Date], "ddd" ),
"Today", TODAY(),
"Fiscal Week", FiscalWeek,
"Current Fiscal Week",
AND( FiscalWeek = TodayFiscalWeek, FiscalYear = TodayFiscalYear )
)
)

Rolling 20 workday revenue

Currently visualizing sales for the past 30days, but looking to switch it in to the past 20 workdays instead, I've got workday column up and running in datetable, so ideally id want to use a filter of workday=1 and grab the 20 newest rows?
Sales 30d =
CALCULATE([Sales],
FILTER(
ALL(d_dates[date]),
d_dates[date]
>TODAY()-30))
This is what im using to show revenue for past 30 days, what'll i need to change?
You can try with this below measure-
slaes_last_20_days =
VAR today = TODAY()
VAR selected_date_min =
MINX(
TOPN(
20,
FILTER(
ALL(d_dates),
d_dates[date].[Date] <= today
&& workday = 1
),
d_dates[date].[Date],
DESC
),
d_dates[date].[Date]
)
RETURN
CALCULATE(
[Sales],
FILTER(
ALL(d_dates),
d_dates[date].[Date] >= selected_date_min
&& workday = 1
)
)
VAR Last20Workdays =
selectcolumns(
TOPN(
20,
FILTER(
d_dates,
d_dates[date] < TODAY()
&& d_dates[workday] = 1
),
d_dates[date],
DESC
),
"WorkDay",
d_dates[date]
)
This worked.