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
knuckledown234
Frequent Visitor

Dynamic date comparisons as filters

For context, my model has two tables, Project and Draft.


Project has a list of Project #s, Draft #s and Project Dates. Note that the Draft numbers are unique.

 

ProjectProject DateDraft #
3971/30/20221
3971/30/20224
3971/30/20225
3971/30/20228
4122/22/20232
4122/22/20233
4122/22/202310
6715/15/20216
6715/15/20217
6715/15/20219
4122/22/202312


The Draft table has a list of Draft #s and their status date when they enter statuses Submitted, Approved and Closed:

Draft #StatusStageStatus DateProject
1Submitted6612/20/2018397
1Approved991/12/2019397
1Closed991/29/2019397
2Submitted6612/1/2019412
2Approved9912/21/2019412
2Closed992/6/2020412
3Submitted666/1/2020412
3Approved997/17/2020412
3Closed997/8/2020412
4Submitted668/14/2020397
4Approved999/18/2020397
4Closed9910/14/2020397
5Submitted666/15/2021397
5Approved997/28/2021397
5Closed998/19/2021397
6Submitted669/12/2021671
6Approved9912/1/2021671
6Closed9911/8/2021671
7Submitted661/1/2023671
7Approved992/16/2023671
7Closed993/14/2023671
8Submitted664/2/2023397
8Approved995/9/2023397
8Closed995/10/2023397
9Submitted668/30/2023671
9Approved999/5/2023671
9Closed999/20/2023671
10Submitted665/17/2023412
10Approved996/5/2023412
10Closed996/28/2023412
12Submitted668/1/2021412


My data model has a physical relationship from Project (1) to Draft (many) on the Draft # field. (Project 1:*Draft)

 

I am planning on building this as a dataset that I will combine with a larger dataset as a composite model, so I do not have a date table (because the larger dataset already has a date table).

 

User request:
The user would like to see the following:

  • The user is only interested in projects with Submission dates between 1/1/2019 - 12/31/2021, closure dates between 1/1/2019 - 12/31/2021, and Approval Dates between 1/1/2019 – 12/31/2021. The user might want to be able to change these dates, for example with a slicer. The user is less interested in constraining the project date.
  • The user would like to see a table like below, with the project number, the project date (from the project table), the most recent approval status date, the most recent closure status date, the most recent submitted status date, and the number of days from the most recent approval status date to the project date:
ProjectMost Recent ApprovalMost Recent ClosureMost Recent SubmissionProject DateDays from Most Recent Approval to Project Date
671 12/1/2021 11/8/2021 9/12/2021 5/15/2021-200

 

  • You might notice that only one project is on this table! That is because:
    • in order for a project to be included on the table, the most recent closure date associated with any project must be BEFORE that project’s most recent approval date (within the above date filters)
    • Finally, in order for a project to be included on the table, the most recent submission date associated with any project must be BEFORE that project’s most recent closure date (within the above date filters)

For my date filter, I have a slicer with the Draft table’s Status Date, since the user may wish to change the range of dates they wish to view. The user potentially wanting to change filter date range is also why I’m hesitant to build a calculated column on the Draft table for “Most Recent Approval Date,” “Most Recent Submission Date,” etc.

 

In Power BI, I created a table visual and dropped in the Project table's Project #.

 

I then dropped in measures for highest approval date, highest closure date, highest submission date, project date, and days between most recent approval and project date. These are those measures:

 

Most Recent Submission Date =
CALCULATE(
MAX('Draft Table'[Status Date])
, 'Draft Table'[Status] in {"Submitted"}
)
 
Most Recent Approval Date =
CALCULATE(
MAX('Draft Table'[Status Date])
, 'Draft Table'[Status] in {"Approved"}
)
 
Most Recent Closure Date =
CALCULATE(
MAX('Draft Table'[Status Date])
, 'Draft Table'[Status] in {"Closed"}
)
 
Project Date =
VAR UniqueID = MAX('Draft Table'[Draft #])
RETURN
CALCULATE(
    MAX('Project'[Project Date])
    , 'Project'[Draft #] IN {UniqueID}
)

 

Days Between Most Recent Approval and Project Date =
DATEDIFF(
    [Most Recent Approval Date]
    , [Project Date]
    , DAY
)

 

I am struggling to filter the table to the final two bullet points (where the project should only appear on the table if the Most Recent Approval Date must be more recent than the Most Recent Closure date, AND if the Most Recent Closure Date is more recent than the most recent Submission Date).

 

I’ve tried building a measure similar to this. My thought is that I would drop this measure into the filter pane and filter to project numbers that return an amount on the measure. However, it takes quite a long time to load on Power BI desktop with the actual data tables. It also doesn’t seem to be returning correct results on my current table.

 

Measure to Filter Table Visual =
VAR Project_Num = SELECTEDVALUE(‘PROJECT’[Project])

 

VAR Approve_date =
CALCULATE(
MAX(‘Draft Table’[Status Date])
, ‘Draft Table’[STATUS] in {“Approved”}
, Project[Project] IN {Project_Num}
)

 

VAR Close_date =
CALCULATE(
MAX(‘Draft Table’[Status Date])
, ‘Draft Table’[STATUS] in {“Closed”}
, Project[Project] IN {Project_Num}
)

 

VAR Submit_Date =
CALCULATE(
MAX(‘Draft Table’[Status Date])
, ‘Draft Table’[STATUS] in {“Submitted”}
, Project[Project] IN {Project_Num}
)

 

VAR ApproveGreaterThanClose =
CALCULATE(
DISTINCTCOUNT(‘Draft Table’[Draft #])
, ‘Project’[Project] IN {Project_Num}
, FILTER(
VALUES(‘Draft Table’)
, ‘Draft Table’ [Status] IN {“Approved”} && ‘Draft Table’[Status Date] > Close_date
)
)

 

VAR CloseGreaterThanSub =
CALCULATE(
DISTINCTCOUNT(‘Draft Table’[Draft #])
, ‘Project’[Project] IN {Project_Num}
, FILTER(
VALUES(‘Draft Table’)
, Submit_date < Close_date
)
)

 

RETURN CloseGreaterThanSub + ApproveGreaterThanClose

 

I feel like I'm not thinking about this correctly, perhaps because I'm building this based off of a SQL query.

 

The SQL query has two CTEs (one for finding the most recent approval dates on projects within the user's requested date range, the second CTE for finding the most recent closure dates on projects within the user's requested date range). The SQL query then joins the the two CTEs to a main query that finds the most recent submission dates on projects within the user's requested date range. The person running the SQL query just changes the dates whenever the user makes a new request, but we're hoping to make the Power BI dashboard more self-service so the user can select those dates. However, I'm not sure how to make the dates easy to filter while also building the table that the user wants.

What are your thoughts? Am I approaching this problem in the wrong way?

1 ACCEPTED SOLUTION
v-yohua-msft
Community Support
Community Support

Hi,   @knuckledown234 

Based on your information, I create two tables.

At the same time, I also created a date table with the minimum State Date as the starting point and the maximum State Date as the end point.

 

 

vyohuamsft_0-1706777165278.png

 

 

Date = ADDCOLUMNS(CALENDAR(MIN('Draft Table'[Status Date]),MAX('Draft Table'[Status Date])),"year",YEAR([Date]))

 

Here are my thoughts:

Create a date table and form a one-to-many relationship with Start Date.

 

vyohuamsft_1-1706777165280.png

 

 

Then create a measure, using the following DAX

 

1.png

 

 Logo = CALCULATE(COUNTAX( FILTER('Draft Table',MIN('Draft Table'[Status Date])<=MIN('Date'[Date])&&MIN('Date'[Date])<=MAX('Draft Table'[Status Date])|| MAX('Date'[Date])>=MAX('Draft Table'[Status Date])&&MAX('Date'[Date])<=MAX('Draft Table'[Status Date])&&[Most Recent Submission Date]<=[Most Recent Closure Date]&&[Most Recent Closure Date]<=[Most Recent Approval Date] ||(MIN('Draft Table'[Status Date])<=MIN('Date'[Date])&&MIN('Date'[Date])<=MAX('Draft Table'[Status Date]))&&[Most Recent Submission Date]<=[Most Recent Closure Date]&&[Most Recent Closure Date]<=[Most Recent Approval Date] ||(MIN('Draft Table'[Status Date])<=MAX('Date'[Date])&&MAX('Date'[Date])<=MAX('Draft Table'[Status Date]))&&[Most Recent Submission Date]<=[Most Recent Closure Date]&&[Most Recent Closure Date]<=[Most Recent Approval Date]),('Draft Table'[Project])), CROSSFILTER('Draft Table'[Status Date],'Date'[Date],None)) 

 

I'm using this measure to determine the required date, when the minimum value of the slicer >=the minimum value of the date table &&< the minimum value of the date table &gt<=closed<=approve or the maximum value of the slicer >=the minimum value of the date table && the maximum value of the date table< = the maximum value of the date table && &<&=closed<=approve, the maximum and minimum values of the data table are within the range of the minimum and maximum values of the slicer.

 

Next, create a slicer and put the Date in the Date table into the Filed.

 

图片1.png

 

Here is my preview:

 

2.png

 

 

 

How to Get Your Question Answered Quickly 

If it does not help, please provide more details with your desired output and pbix file without privacy information (or some sample data) .

Best Regards

Yongkang Hua

If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

View solution in original post

4 REPLIES 4
knuckledown234
Frequent Visitor

I'd like to circle back to thank @amitchandak and @v-yohua-msft for their contributions to this topic! My original post was very vague for such a complex scenario. To make things even more complex, my user changed their parameters a couple of times, too.

@amitchandak's tutorials on LASTDATE() were thought-provoking, thank you so much!

@v-yohua-msft's suggestion to include a Date table and write a nested series of formulas was very helpful. Because I felt the solution I ultimately chose was similar to @v-yohua-msft, I am giving him kudos.

 

Here is what I ultimately did.

  • In a dataflow, I combined the Draft and Project tables into one table, Project_Draft_Join. If you don't have premium license, you can use a native query to do this.
  • I added a date table. I think because I was planning on adding this dataset to another as a composite dataset, I resisted using a date table. However, I think adding the date table and placing 'Date'[Date] into the date selection slicer per v-yohua-msft's suggestion helped me solve the problem.

For my end result visuals, I created the following:

A "Between" style date slicer with 'Date'[Date] thrown in

A table visual with the newly combined table's "Project #" field tossed, as well as helper measures.

 

In the filter pane for the table visual, I placed this measure:

Project Matches User Requirements =

VAR Project_Num = SELECTEDVALUE(Project_Draft_Join'[PROJECT])

VAR Submit_Date = {[Most Recent Submit Date]}

VAR Approve_date = {[Most Recent Approve Date]}

Var Close_date_Measure = {[Most Recent Close Date]}

     

 

RETURN

IF(

    COUNTROWS(Submit_date) > 0  

        && Close_date_Measure > Submit_Date

        && Close_date_Measure < Approve_Date

    , CALCULATE(

        COUNT('Project_Draft_Join'[DRAFT #])

        ,  'Project_Draft_Join'[Status] in {"Submitted"} // Status is "Submitted"

        , 'Project_Draft_Join'[PROJECT] IN {Project_Num}

    )

)

I added a filter to only show items where the value is NOT blank.

 

As an example of one of my helper measures that I placed in the table, please see the measure I created to see the most recent "Submitted" status on a project and the Project date associated with that Submitted Status. I dropped this into the table visual "Fields" list:

 

Most Recent Submit Date Measure =

CALCULATE(

    MAX('Project_Draft_Join'[Status Date])

    , 'Project_Draft_Join'[Status] in {"Submitted"}

    , USERELATIONSHIP('Project_Draft_Join'[Status Date], 'Calendar'[Date])

)

 

This is a measure to see the most recent Approval, which I also dropped in the table visual:

 

Most Recent Approval Date =

 

CALCULATE(

    LASTDATE('Project_Draft_Join'[Status Date])

    , REMOVEFILTERS('Calendar'[Date]) // One of my user's new requests was that the Approval date NOT be bound by the same date filter as the submission date, but the Approval date must be AFTER the submission date and closed date

    , 'Project_Draft_Join'[status] in {"Approved"}

)

 

This is the measure to find the most recent Project Date, which I also dropped in the table fields list:

 

Project Date for most Recent Submission Date on Project =

VAR MostRecentSubbed =

CALCULATE(

    MAX('Project_Draft_Join'[Status Date])

    , 'Project_Draft_Join'[Status] in {"Submitted"}

)

VAR DraftNum =

CALCULATE(

    SELECTEDVALUE('Project_Draft_Join'[Draft #])

    , 'Project_Draft_Join'[Status Date] = MostRecentSubbed

    , 'Project_Draft_Join'[Status] in {"Submitted"}

)      

     

RETURN

 

CALCULATE(

    SELECTEDVALUE('Project_Draft_Join'[Project Date])

    , 'Project_Draft_Join' [Draft #] = DraftNum

)

 

The user wants to see the number of days from the Project Date to the Approval Date. To obtain this, I wrote the following and dropped the measure in the table fields list:

PROJECT DATE MINUS MOST RECENT APPROVED MEASURE =

VAR MOSTRECENTAPPROVED = {[Most Recent Approval Date]}

VAR MostRecentProjectDate = {[Project Date for most Recent Submission Date on Project]}

return

DATEDIFF(

    MOSTRECENTAPPROVED

    , MostRecentProjectDate

    , DAY

)

 

 

 

I also created two card visuals: One to hold a measure to count the projects, one to hold a median measure for days between renewal and approval.

 

To obtain the count, I wrote the following:

Count projects within parameters and return a total count at total line scope =

VAR Project_num = SELECTEDVALUE('Project_Draft_Join'[PROJECT])

VAR Submit_Date = {[Most Recent Submit Date]}

VAR Approve_date = {[Most Recent Approval Date]}

Var Close_date_Measure = {[Most Recent Closed Date]}

     

 

RETURN

 

IF(

    ISINSCOPE('Project_Draft_Join'[PROJECT]) // if the current visual row has one project number, follow the next IF() statement

    , IF(

        COUNTROWS(Submit_date) > 0  // At least one submission is found within the date range

            && Close_date_Measure > Submit_Date // Closure date is after submit date

            && Close_date_Measure < Approve_Date // Approval date is after closure date

        , CALCULATE(

            COUNT('Project_Draft_Join'[DRAFT #])

            ,  'Project_Draft_Join'[status] in {"Submitted"} // Status is "Submitted"

            , 'Project_Draft_Join'[PROJECT] IN {Project_num}

        )

    ), COUNTROWS( // This returns a total count for table visuals with a "Total" values row.

        FILTER(

            ADDCOLUMNS(

                SUMMARIZE(

                    'Project_Draft_Join'

                    , 'Project_Draft_Join'[PROJECT]

                ), "MARK", [Project Matches User Requirements]

            ), NOT ISBLANK([Mark])

    )

    )

)

 

 

 

To obtain the median, I used this formula:

Median Days from Approval to Project Date =

VAR Project_num = SELECTEDVALUE('Project_Draft_Join'[PROJECT])

VAR Submit_Date = {[Most Recent Submit Date]}

VAR Approve_date = {[Most Recent Approval Date]}

Var Close_date_Measure = {[Most Recent Closed Date]}

     

 

RETURN

 

IF(

    ISINSCOPE('Project_Draft_Join'[PROJECT])

    , IF(

        COUNTROWS(Submit_date) > 0  

            && Close_date_Measure > Submit_Date

            && Close_date_Measure < Approve_Date

        , MEDIANX(

            FILTER(

                VALUES('Project_Draft_Join'[PROJECT])

                , NOT ISBLANK([PROJECT DATE MINUS MOST RECENT APPROVED MEASURE])

                    && NOT ISBLANK([Project Matches User Requirements])

            ), [PROJECT DATE MINUS MOST RECENT APPROVED MEASURE]

        )

    ), MEDIANX( // This returns a total median for table visuals with a "Total" values row.

        FILTER(

            VALUES('Project_Draft_Join'[PROJECT])

            , NOT ISBLANK([PROJECT DATE MINUS MOST RECENT APPROVED MEASURE])

                && NOT ISBLANK([Project Matches User Requirements])

        ), [PROJECT DATE MINUS MOST RECENT APPROVED MEASURE]

    )

)

 

I used the above two measures in the cards only, where the path for "Totals" would display. When I added the above two measures to the table, they were too expensive for Power BI desktop to compute. For the table visual, I turned off "Totals" and used the more basic measures. 

I hope this topic helps someone with a similar problem! Thank you both again for all of your help!

 

 

 

v-yohua-msft
Community Support
Community Support

Hi,   @knuckledown234 

Based on your information, I create two tables.

At the same time, I also created a date table with the minimum State Date as the starting point and the maximum State Date as the end point.

 

 

vyohuamsft_0-1706777165278.png

 

 

Date = ADDCOLUMNS(CALENDAR(MIN('Draft Table'[Status Date]),MAX('Draft Table'[Status Date])),"year",YEAR([Date]))

 

Here are my thoughts:

Create a date table and form a one-to-many relationship with Start Date.

 

vyohuamsft_1-1706777165280.png

 

 

Then create a measure, using the following DAX

 

1.png

 

 Logo = CALCULATE(COUNTAX( FILTER('Draft Table',MIN('Draft Table'[Status Date])<=MIN('Date'[Date])&&MIN('Date'[Date])<=MAX('Draft Table'[Status Date])|| MAX('Date'[Date])>=MAX('Draft Table'[Status Date])&&MAX('Date'[Date])<=MAX('Draft Table'[Status Date])&&[Most Recent Submission Date]<=[Most Recent Closure Date]&&[Most Recent Closure Date]<=[Most Recent Approval Date] ||(MIN('Draft Table'[Status Date])<=MIN('Date'[Date])&&MIN('Date'[Date])<=MAX('Draft Table'[Status Date]))&&[Most Recent Submission Date]<=[Most Recent Closure Date]&&[Most Recent Closure Date]<=[Most Recent Approval Date] ||(MIN('Draft Table'[Status Date])<=MAX('Date'[Date])&&MAX('Date'[Date])<=MAX('Draft Table'[Status Date]))&&[Most Recent Submission Date]<=[Most Recent Closure Date]&&[Most Recent Closure Date]<=[Most Recent Approval Date]),('Draft Table'[Project])), CROSSFILTER('Draft Table'[Status Date],'Date'[Date],None)) 

 

I'm using this measure to determine the required date, when the minimum value of the slicer >=the minimum value of the date table &&< the minimum value of the date table &gt<=closed<=approve or the maximum value of the slicer >=the minimum value of the date table && the maximum value of the date table< = the maximum value of the date table && &<&=closed<=approve, the maximum and minimum values of the data table are within the range of the minimum and maximum values of the slicer.

 

Next, create a slicer and put the Date in the Date table into the Filed.

 

图片1.png

 

Here is my preview:

 

2.png

 

 

 

How to Get Your Question Answered Quickly 

If it does not help, please provide more details with your desired output and pbix file without privacy information (or some sample data) .

Best Regards

Yongkang Hua

If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

I would like to make sure I understand your FILTER conditions. I'm a little confused about how they are grouped together, since some of them seem to repeat and only a couple are "grouped" together in parentheses.

 

Condition 1: the earliest Status Date must be on/before the earliest date selection on the slicer
AND C2: the most recent Status Date must be on/after the most earliest date selection on the slicer

OR C3: the most recent Status Date must be on/before the most recent date selection on the slicer
AND C4: the most recent Status Date must be on/after the most recent date selection on the slicer
AND C5: Most recent submission date must be on/before the most recent closure date
AND C6: Most recent closure date must be on/before the most recent approval date
OR Group of Conditions A:
Group of Conditions A, C1: Earliest status date must be on/before earliest slicer selection
AND Group of Conditions A, C2: Earliest status date must be on/before most recent slicer selection

End Group of Conditions A
AND C7: Most recent submission date must be on/before the most recent closure date
AND
 C8: Most recent closure date must be on/before the most recent approval date

OR (Begin Group of Conditions B
Group of Conditions B, C1: Earliest status date must be on/before most recent slicer selection
AND Group of Conditions B, C2: Most recent slicer selection must be on/before most recent status date

End GRoup of Conditions B
AND C9: Most recent submission date must be on/before the most recent closure date
AND
 C10: Most recent closure date must be on/before the most recent approval date


Logo =
CALCULATE (
    COUNTAX (
        FILTER (
            'Draft Table',
            MIN ( 'Draft Table'[Status Date] ) <= MIN ( 'Date'[Date] )
// Condition 1: the earliest Status Date must be on/before the earliest date selection on the slicer

                && MIN ( 'Date'[Date] ) <= MAX ( 'Draft Table'[Status Date] 
// Condition 2: the most recent Status Date must be on/after the most earliest date selection on the slicer

                || MAX ( 'Date'[Date] ) >= MAX ( 'Draft Table'[Status Date] 
// C3: the most recent Status Date must be on/before the most recent date selection on the slicer

                    && MAX ( 'Date'[Date] ) <= MAX ( 'Draft Table'[Status Date] 
// C4: the most recent Status Date must be on/after the most recent date selection on the slicer

                    && [Most Recent Submission Date] <= [Most Recent Closure Date]
// C5: Most recent submission date must be on/before the most recent closure date

                    && [Most Recent Closure Date] <= [Most Recent Approval Date] 
// C6: Most recent closure date must be on/before the most recent approval date

                || ( // Beginning of group of conditions A
                    MIN ( 'Draft Table'[Status Date] ) <= MIN ( 'Date'[Date] )

// Group of Conditions A, C1: Earliest status date must be on/before earliest slicer selection
                        && MIN ( 'Date'[Date] ) <= MAX ( 'Draft Table'[Status Date] )

// Group of Conditions A, C2: Earliest status date must be on/before most recent slicer selection

                ) // End group of conditions A
                    && [Most Recent Submission Date] <= [Most Recent Closure Date]

// C7: Most recent submission date must be on/before the most recent closure date
                    && [Most Recent Closure Date] <= [Most Recent Approval Date]

// C8: Most recent closure date must be on/before the most recent approval date
                || ( // Begin Group of Conditions B
                    MIN ( 'Draft Table'[Status Date] ) <= MAX ( 'Date'[Date] )

// Group of Conditions B, C1: Earliest status date must be on/before most recent slicer selection
                        && MAX ( 'Date'[Date] ) <= MAX ( 'Draft Table'[Status Date] )

// Group of Conditions B, C2: Most recent slicer selection must be on/before most recent status date
                ) // End GRoup of Conditions B
                    && [Most Recent Submission Date] <= [Most Recent Closure Date]

// C9: Most recent submission date must be on/before the most recent closure date
                    && [Most Recent Closure Date] <= [Most Recent Approval Date]

// C10: Most recent closure date must be on/before the most recent approval date        ),
        ( 'Draft Table'[Project] )
    ),
    CROSSFILTER ( 'Draft Table'[Status Date], 'Date'[Date], NONE )
)

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.