Forum Discussion

qmestu's avatar
qmestu
Icon for Helper IV rankHelper IV
8 months ago
Solved

How to count indicators per classification based on the latest date (DAX)

Hi,

 

Using the sample data below, how can I calculate the count of indicators per classification, considering only the latest available date for each indicator? The DAX measure I’m using currently counts the same indicator multiple times.

CALCULATE(DISTINCTCOUNT(Table[Indicator-Key]), LASTDATE(Table[Date]))

 

 

QuarterIndicator-KeyClassificationIndicatorCodeMonthQuarterLabelMonthYearDateDepartmentQuarter-Year
Q1IND-X7-Q1ExceededIND-X7MarQ12025-0301/03/2025 00:00Dept-A2025 Q1
Q1IND-A3-Q1ExceededIND-A3MarQ12025-0301/03/2025 00:00Dept-A2025 Q1
Q1IND-F9-Q1ExceededIND-F9MarQ12025-0301/03/2025 00:00Dept-A2025 Q1
Q1IND-M2-Q1ExceededIND-M2MarQ12025-0301/03/2025 00:00Dept-A2025 Q1
Q1IND-K4-Q1Not ClassifiedIND-K4JanQ12025-0101/01/2025 00:00Dept-A2025 Q1
Q1IND-K4-Q1Not ClassifiedIND-K4FebQ12025-0201/02/2025 00:00Dept-A2025 Q1
Q1IND-K4-Q1Not ClassifiedIND-K4MarQ12025-0301/03/2025 00:00Dept-A2025 Q1
Q1IND-R8-Q1Not ClassifiedIND-R8JanQ12025-0101/01/2025 00:00Dept-A2025 Q1
Q1IND-R8-Q1Not ClassifiedIND-R8FebQ12025-0201/02/2025 00:00Dept-A2025 Q1
Q1IND-R8-Q1Not ClassifiedIND-R8MarQ12025-0301/03/2025 00:00Dept-A2025 Q1
Q1IND-P5-Q1Not ClassifiedIND-P5JanQ12025-0101/01/2025 00:00Dept-A2025 Q1
Q1IND-P5-Q1Not ClassifiedIND-P5FebQ12025-0201/02/2025 00:00Dept-A2025 Q1
Q1IND-P5-Q1Not ClassifiedIND-P5MarQ12025-0301/03/2025 00:00Dept-A2025 Q1
Q1IND-D6-Q1ExceededIND-D6JanQ12025-0101/01/2025 00:00Dept-A2025 Q1
Q1IND-D6-Q1ExceededIND-D6FebQ12025-0201/02/2025 00:00Dept-A2025 Q1
Q1IND-D6-Q1ExceededIND-D6MarQ12025-0301/03/2025 00:00Dept-A2025 Q1
  • Hello,
    I think the issue is that LASTDATE(Table[Date]) returns only the last date in the current filter context, so indicators that have multiple months in the same quarter are still counted multiple times
    what you need instead is to first identify, for each Indicator-Key, its own latest available date, and then count indicators only on those rows

    you can do it like this:

     

    Indicators Latest :=
    CALCULATE(
        DISTINCTCOUNT(Table[Indicator-Key]),
        FILTER(
            Table,
            Table[Date]
                = CALCULATE(
                    MAX(Table[Date]),
                    ALLEXCEPT(Table, Table[Indicator-Key])
                )
        )
    )

    This should works because, for every indicator, it keeps only the row where the date is the maximum for that indicator, and all earlier months are ignored,
    when you put Classification on rows, the indicator is counted only once, under its latest classification.

9 Replies

  • Hello,
    I think the issue is that LASTDATE(Table[Date]) returns only the last date in the current filter context, so indicators that have multiple months in the same quarter are still counted multiple times
    what you need instead is to first identify, for each Indicator-Key, its own latest available date, and then count indicators only on those rows

    you can do it like this:

     

    Indicators Latest :=
    CALCULATE(
        DISTINCTCOUNT(Table[Indicator-Key]),
        FILTER(
            Table,
            Table[Date]
                = CALCULATE(
                    MAX(Table[Date]),
                    ALLEXCEPT(Table, Table[Indicator-Key])
                )
        )
    )

    This should works because, for every indicator, it keeps only the row where the date is the maximum for that indicator, and all earlier months are ignored,
    when you put Classification on rows, the indicator is counted only once, under its latest classification.

    • qmestu's avatar
      qmestu
      Icon for Helper IV rankHelper IV

      Thank you. I tried the formula that you added and it counted blank. I then added more columns to the allexcept statement, as i'm using QuarterYear and Department as slicers and page-level filters. However, my count is different when in don't include classification on the chart.

       

      For example, i get 14 in total my count. But if i include classification on that chart, i get 5+9+1+2+1, which doesn't add up to 14.

    • qmestu's avatar
      qmestu
      Icon for Helper IV rankHelper IV

      Although i ended up using the summarize function to generate a new table with just the latest results, your hint about why lastdate was not correct pointed me the right way. So i've marked your answer as a solution. Thanks.

  • Hi qmestu ,

    The issue with your current measure is that LASTDATE evaluates based on the current context (e.g., the entire quarter), but it does not evaluate row-by-row for each indicator to find its specific latest date. This causes "semi-additive" issues where an indicator might be counted against multiple classifications if its status changed during the selected period.

    To count each indicator only once,based on its latest status within the selected period,you need to identify the max date for each indicator first, and then filter the data to those specific rows.

    Here is the most performant DAX pattern (using TREATAS) to achieve this:

    The Solution: "Last Non-Empty" Pattern

    Count Latest Classification = 
    VAR _MaxDatesPerIndicator = 
        ADDCOLUMNS(
            VALUES('Table'[Indicator-Key]),
            "LatestDate", CALCULATE(MAX('Table'[Date]))
        )
    
    RETURN
        CALCULATE(
            DISTINCTCOUNT('Table'[Indicator-Key]),
            -- This effectively filters the table to keep ONLY the latest row for each indicator
            TREATAS(_MaxDatesPerIndicator, 'Table'[Indicator-Key], 'Table'[Date])
        )

    Why this works:

    1. VAR _MaxDatesPerIndicator: It creates a virtual table in memory containing a list of every visible Indicator and its corresponding Max Date (e.g., IND-X7 | 01/03/2025).

    2. TREATAS: It takes this virtual list and applies it as a strict filter to the data model.

    3. Result: The calculation DISTINCTCOUNT now only sees the rows that match those latest dates.

      • If you put "Classification" in a visual (table/chart), an indicator will only appear under its classification from that latest date.

      • If an indicator changed from "Not Classified" (Jan) to "Exceeded" (Mar), this measure ensures it is only counted as "Exceeded".

    Note on Performance: The solution suggested by @DanieleUgoCopp using FILTER(Table, ...) is logically correct, but the TREATAS approach above is significantly faster on larger datasets because it avoids iterating through the entire fact table row-by-row.


    If my response resolved your query, kindly mark it as the Accepted Solution to assist others. Additionally, I would be grateful for a 'Kudos' if you found my response helpful.
    This response was assisted by AI for translation and formatting purposes.

    • qmestu's avatar
      qmestu
      Icon for Helper IV rankHelper IV

      Hi,

       

      Thank you. How can i modify your expression, so that doesn't count rows where Indicator-Key has a blank value in another column (not pictured in the sample data)?

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

        qmestu , Try like 

        Calculate(lastnonblankvalue(Table[Date], DISTINCTCOUNT(Table[Indicator-Key])), not(isblank(Table[Indicator-Key])))

  • Use a “latest row per indicator” virtual table, then count indicators in that reduced set (so each Indicator-Key appears once).

     

    Indicators (Latest) =
    VAR LatestPerIndicator =
        ADDCOLUMNS (
            VALUES ( 'Table'[Indicator-Key] ),
            "__LatestDate", CALCULATE ( MAX ( 'Table'[Date] ) )
        )
    VAR LatestRows =
        TREATAS (
            SELECTCOLUMNS ( LatestPerIndicator, "Indicator-Key", [Indicator-Key], "Date", [__LatestDate] ),
            'Table'[Indicator-Key], 'Table'[Date]
        )
    RETURN
    CALCULATE (
        DISTINCTCOUNT ( 'Table'[Indicator-Key] ),
        LatestRows
    )

     

    Put Classification on rows/columns and this measure in Values, it will count each indicator only once, based on its latest available Date in the current filter context.

    • qmestu's avatar
      qmestu
      Icon for Helper IV rankHelper IV

      Thank you. But all of the solutions provided here have the same problem. In a chart, the value without classification is one, and with classification it's another. When they should add up to the same thing.