Forum Discussion

o-johnralphp's avatar
o-johnralphp
Icon for Advocate I rankAdvocate I
10 months ago
Solved

Lookup for 2 Date Range from 2 Tables

Hello everyone!

 

Im trying to get the Event in Activity Table through a calculated column if the Activity Start and End is within the range of those on the Event Table.

 

Thanks for the help!

 

Activity Table
ActivityStartEndEvent (Desired Output)
107/03/2023 9:4207/03/2023 23:59No Event
205/01/2025 13:5605/01/2025 23:59A
308/01/2025 11:1408/01/2025 20:15D

 

 

 

Event Table
EventStartEnd
A05/01/2025 14:5605/01/2025 17:00
B07/05/2023 9:4207/05/2023 23:59
C07/06/2023 7:0007/06/2023 9:45
D08/01/2025 11:1408/01/2025 23:15

 

 

  • Hi o-johnralphp,

     

    You’re matching each Activity to the single Event whose time window fully contains the Activity window (Event.Start <= Activity.Start and Event.End >= Activity.End). A calculated column on Activity is fine for this.

    Below are two DAX options:

    • Containment match (your stated requirement): Activity must be entirely within the Event.
    • Overlap match (if you later decide any overlap counts): Activity overlaps Event in any way.

    I’ve also added a simple tie-breaker in case multiple Events fit: pick the one with the earliest Event.Start. You can tweak that if you prefer a different rule.

    Event (calculated column) =
    VAR aStart = Activity[Start]
    VAR aEnd   = Activity[End]
    VAR Candidates =
        FILTER (
            Event,                               -- or 'Events' if that's your table name
            Event[Start] <= aStart
                && Event[End] >= aEnd            -- full containment
        )
    VAR FirstMatch =
        TOPN ( 1, Candidates, Event[Start], ASC )   -- tie-break: earliest Event.Start
    RETURN
    COALESCE (
        CALCULATE ( SELECTEDVALUE ( Event[Event] ), FirstMatch ),
        "No Event"
    )

    If instead you want any overlap (not full containment), change the FILTER to:

    FILTER (
        Events,
        Events[Start] < aEnd
            && Events[End] > aStart            -- any overlap
    )

     

    • Why a calculated column? You want a stable row-by-row lookup at refresh time. This avoids context complications from visuals.
    • Why not LOOKUPVALUE? LOOKUPVALUE does equality matches; your requirement uses inequalities (<=, >=), so we filter Events instead.
    • Tie-breaking: If multiple Events qualify, TOPN(1, ..., Events[Start], ASC) picks the earliest-starting Event. Replace with Events[End], DESC (latest ending) or another column if you prefer.
    • No match: COALESCE(..., "No Event") outputs “No Event” when no Event window contains the Activity window.
    • Performance tip: If Events is large, consider indexing/sorting in Power Query or materializing ranges (e.g., date keys) to reduce per-row scans. But for a modest Events table this pattern is fine.

    EDIT: 
    Fixed the issue of the measure returning a table instead of a value for the calculate. 
    Here is a link to the working file: https://drive.google.com/file/d/1e7219J5pMPaabFfmaJsxiXJsztwrxdki/view?usp=sharing

     

    If you found this helpful, consider giving some Kudos. If I answered your question or solved your problem, mark this post as the solution.

  • Hi o-johnralphp 

    try this:

    Event = 
    VAR _start = Activity[Start]
    VAR _end = Activity[End]
    VAR filteredTable =
        FILTER ( Events, Events[Start] <= _end && Events[End] >= _start )
    VAR _TopN =
        --sort by [Start] in ascending order if there are multiple records then select the first one
        TOPN ( 1, filteredTable, [Start], ASC ) 
    RETURN
        COALESCE ( MINX ( _TopN, [Event] ), "No event" )
    

     

9 Replies

  • Hi o-johnralphp,

     

    You’re matching each Activity to the single Event whose time window fully contains the Activity window (Event.Start <= Activity.Start and Event.End >= Activity.End). A calculated column on Activity is fine for this.

    Below are two DAX options:

    • Containment match (your stated requirement): Activity must be entirely within the Event.
    • Overlap match (if you later decide any overlap counts): Activity overlaps Event in any way.

    I’ve also added a simple tie-breaker in case multiple Events fit: pick the one with the earliest Event.Start. You can tweak that if you prefer a different rule.

    Event (calculated column) =
    VAR aStart = Activity[Start]
    VAR aEnd   = Activity[End]
    VAR Candidates =
        FILTER (
            Event,                               -- or 'Events' if that's your table name
            Event[Start] <= aStart
                && Event[End] >= aEnd            -- full containment
        )
    VAR FirstMatch =
        TOPN ( 1, Candidates, Event[Start], ASC )   -- tie-break: earliest Event.Start
    RETURN
    COALESCE (
        CALCULATE ( SELECTEDVALUE ( Event[Event] ), FirstMatch ),
        "No Event"
    )

    If instead you want any overlap (not full containment), change the FILTER to:

    FILTER (
        Events,
        Events[Start] < aEnd
            && Events[End] > aStart            -- any overlap
    )

     

    • Why a calculated column? You want a stable row-by-row lookup at refresh time. This avoids context complications from visuals.
    • Why not LOOKUPVALUE? LOOKUPVALUE does equality matches; your requirement uses inequalities (<=, >=), so we filter Events instead.
    • Tie-breaking: If multiple Events qualify, TOPN(1, ..., Events[Start], ASC) picks the earliest-starting Event. Replace with Events[End], DESC (latest ending) or another column if you prefer.
    • No match: COALESCE(..., "No Event") outputs “No Event” when no Event window contains the Activity window.
    • Performance tip: If Events is large, consider indexing/sorting in Power Query or materializing ranges (e.g., date keys) to reduce per-row scans. But for a modest Events table this pattern is fine.

    EDIT: 
    Fixed the issue of the measure returning a table instead of a value for the calculate. 
    Here is a link to the working file: https://drive.google.com/file/d/1e7219J5pMPaabFfmaJsxiXJsztwrxdki/view?usp=sharing

     

    If you found this helpful, consider giving some Kudos. If I answered your question or solved your problem, mark this post as the solution.

    • o-johnralphp's avatar
      o-johnralphp
      Icon for Advocate I rankAdvocate I

      Hi tayloramy 

      Thanks for the reply. I'm getting an error "The expression refers to multiple columns.Multiple columns cannot converted to a scalar value". I already formatted the necessary columns as Date/Time format.

      • tayloramy's avatar
        tayloramy
        Icon for Super User rankSuper User

        Hi o-johnralphp

        I have edited my reponse to correct that. I was working with a subset of data, only one event and one activity, so my results only returned one record as there was only one record to return. Note to self: Use more complete sample data. 

        Here is a link to the PBIC file with a working solution: https://drive.google.com/file/d/1e7219J5pMPaabFfmaJsxiXJsztwrxdki/view?usp=sharing

         

         If you found this helpful, consider giving some Kudos. If I answered your question or solved your problem, mark this post as the solution.

  • Hi o-johnralphp 

    try this:

    Event = 
    VAR _start = Activity[Start]
    VAR _end = Activity[End]
    VAR filteredTable =
        FILTER ( Events, Events[Start] <= _end && Events[End] >= _start )
    VAR _TopN =
        --sort by [Start] in ascending order if there are multiple records then select the first one
        TOPN ( 1, filteredTable, [Start], ASC ) 
    RETURN
        COALESCE ( MINX ( _TopN, [Event] ), "No event" )