Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.

Reply
mark_endicott
Helper II
Helper II

RLS DAX to provide dynamic BETWEEN where a user can have multiple rows

Hi, 

 

I'm trying to wrap my head around a complex RLS rule, where we need to filter the a column of a table to all the values between a start and an end point in the RLS table, however the complication is, a user can have multiple rows in the RLS table, and therefore multiple start and end values. 

 

The RLS table is in the strutcture below:

 

usernameterritory_codetime_grainstart_tgd_keyend_tgd_key
Test@test.comAUWeek1120024911299901
Test@test.comAUPeriod1220024912299901
Test@test.comAUQuarter1320024913299901
Test@test.comIEWeek4120024941299901
Test@test.comIEPeriod4220024942299901
Test@test.comIEQuarter4320024943299901
Test@test.comNZWeek9120084991299901
Test@test.comNZPeriod9220084992299901
Test@test.comNZQuarter9320084993299901
Test@test.comUKWeek111199801111299901
Test@test.comUKPeriod112199801112299901
Test@test.comUKQuarter113199801113299901

 

And the table that the rule will be imposed upon like below:

 

Stat_weekterritory_codetime_graintgd_key
199801UKWeek111199801
199801UKPeriod112199801
199801UKQuarter113199801
200249AUWeek11200249
200249AUPeriod12200249
200249AUQuarter13200249
200249IEWeek41200249
200249IEPeriod42200249
200249IEQuarter43200249
200849NZWeek91200849
200849NZPeriod92200849
200849NZQuarter93200849

 

The rule needs to match the territory_code & time_grain values between tables, and then filter to all the values in tgd_key that are between the start_tgd_key and end_tgd_key. 

 

My starting point is the code below, which worked until we had to make it mulitple rows per user. 

 

 

VAR Start_filter =
    CALCULATETABLE (
        VALUES ( 'rls account_calendar_meta'[start_tgd_key] ),
        'rls account_calendar_meta'[username] = USERPRINCIPALNAME ()
    )

	
VAR End_filter =
    CALCULATETABLE (
        VALUES ( 'rls account_calendar_meta'[end_tgd_key] ),
        'rls account_calendar_meta'[username] = USERPRINCIPALNAME ()
    )
RETURN
    AND ( [tgd_key] >= Start_filter, [tgd_key] <= End_filter )

 

 

Grateful for any assistance that can be provided!!

 

Thanks,

Mark

1 ACCEPTED SOLUTION
OwenAuger
Super User
Super User

Hi @mark_endicott 

Here are a couple of equivalent RLS filter expressons I would suggest:

(replace FactTable with the correct name)

VAR UPN = USERPRINCIPALNAME ( )
VAR CurrentTerritory =
    FactTable[territory_code]
VAR CurrentTimeGrain =
    FactTable[time_grain]
VAR CurrentTGDKey =
    FactTable[tgd_key]
RETURN
    CALCULATE (
        NOT ISEMPTY ( 'rls account_calendar_meta' ),
        'rls account_calendar_meta'[username] = UPN,
        'rls account_calendar_meta'[territory_code] = CurrentTerritory,
        'rls account_calendar_meta'[time_grain] = CurrentTimeGrain,
        CurrentTGDKey >= 'rls account_calendar_meta'[start_tgd_key],
        CurrentTGDKey <= 'rls account_calendar_meta'[end_tgd_key]
    )

 

VAR UPN = USERPRINCIPALNAME ( )
VAR CurrentTerritory = FactTable[territory_code]
VAR CurrentTimeGrain = FactTable[time_grain]
VAR CurrentTGDKey = FactTable[tgd_key]
RETURN
    CALCULATE (
        NOT ISEMPTY ( 'rls account_calendar_meta' ),
        TREATAS (
            { ( UPN, CurrentTerritory, CurrentTimeGrain ) },
            'rls account_calendar_meta'[username],
            'rls account_calendar_meta'[territory_code],
            'rls account_calendar_meta'[time_grain]
        ),
        CurrentTGDKey >= 'rls account_calendar_meta'[start_tgd_key],
        CurrentTGDKey <= 'rls account_calendar_meta'[end_tgd_key]
    )

The logic is to filter the 'rls account_calendar_meta' table based on the current fact table row, and return TRUE if 'rls account_calendar_meta' is nonempty.

 

Do these work for you?

 

Regards


Owen Auger
Did I answer your question? Mark my post as a solution!
Blog
Twitter
LinkedIn

View solution in original post

2 REPLIES 2
mark_endicott
Helper II
Helper II

@OwenAuger - Thank you so much, both these rules work.

 

Having tested their impact through DAX Studio the version with TREATAS is the most optimal. More optimal in fact than a direct (m-to-m) join on all the possible values of [tgd_key] e.g. listing the [tgd_keys] in rls account_caledar_meta rather than using a start and end. 

I knew I needed to match on the [territory_code] and [time_grain] values, but I couldnt quite see how I was going to bring these values from the fact into my variables - it was actually more simple than I was making it. However I wouldnt have got to your NOT ISEMPTY solution at the end, so once again THANK YOU!!

OwenAuger
Super User
Super User

Hi @mark_endicott 

Here are a couple of equivalent RLS filter expressons I would suggest:

(replace FactTable with the correct name)

VAR UPN = USERPRINCIPALNAME ( )
VAR CurrentTerritory =
    FactTable[territory_code]
VAR CurrentTimeGrain =
    FactTable[time_grain]
VAR CurrentTGDKey =
    FactTable[tgd_key]
RETURN
    CALCULATE (
        NOT ISEMPTY ( 'rls account_calendar_meta' ),
        'rls account_calendar_meta'[username] = UPN,
        'rls account_calendar_meta'[territory_code] = CurrentTerritory,
        'rls account_calendar_meta'[time_grain] = CurrentTimeGrain,
        CurrentTGDKey >= 'rls account_calendar_meta'[start_tgd_key],
        CurrentTGDKey <= 'rls account_calendar_meta'[end_tgd_key]
    )

 

VAR UPN = USERPRINCIPALNAME ( )
VAR CurrentTerritory = FactTable[territory_code]
VAR CurrentTimeGrain = FactTable[time_grain]
VAR CurrentTGDKey = FactTable[tgd_key]
RETURN
    CALCULATE (
        NOT ISEMPTY ( 'rls account_calendar_meta' ),
        TREATAS (
            { ( UPN, CurrentTerritory, CurrentTimeGrain ) },
            'rls account_calendar_meta'[username],
            'rls account_calendar_meta'[territory_code],
            'rls account_calendar_meta'[time_grain]
        ),
        CurrentTGDKey >= 'rls account_calendar_meta'[start_tgd_key],
        CurrentTGDKey <= 'rls account_calendar_meta'[end_tgd_key]
    )

The logic is to filter the 'rls account_calendar_meta' table based on the current fact table row, and return TRUE if 'rls account_calendar_meta' is nonempty.

 

Do these work for you?

 

Regards


Owen Auger
Did I answer your question? Mark my post as a solution!
Blog
Twitter
LinkedIn

Helpful resources

Announcements
Microsoft Fabric Learn Together

Microsoft Fabric Learn Together

Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City

PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

Check out the April 2024 Power BI update to learn about new features.

April Fabric Community Update

Fabric Community Update - April 2024

Find out what's new and trending in the Fabric Community.