Courseiva

PL-300 Visualize and analyze the data Practice Question

You have a Power BI semantic model with a date table that has a 1:* relationship to a Sales table. You need to create a measure that shows the number of sales transactions for the last 30 days. The date table is marked as a date table. Which DAX expression should you use?

Answer choices

Why each option matters

Answer the question above first, then reveal the full breakdown to understand why each option is right or wrong.

Correct answer & explanation

✓

CALCULATE(COUNTROWS(Sales), DATESINPERIOD('Date'[Date], MAX('Date'[Date]), -30, DAY))

DATESINPERIOD('Date'[Date], MAX('Date'[Date]), -30, DAY) returns a 30-day rolling window ending at the last date in the current filter context, which is exactly what a 'last 30 days' measure requires when the model has a marked date table. Wrapping it in CALCULATE with COUNTROWS(Sales) then counts the Sales rows whose related Date values fall in that window. Option B uses DATESBETWEEN with TODAY()-30 and TODAY(), which hard-codes the window to the actual current date rather than the model's latest date and can return blank or wrong results if the data is not current. Option C uses PREVIOUSMONTH, which returns the entire prior calendar month, not a 30-day period. Option D uses DATEADD with -30 DAY, which shifts the current filter context back 30 days rather than returning a 30-day range, so it does not produce a rolling 30-day count.

Answer analysis

Option-by-option breakdown

For each option: why learners choose it and why it is or isn't the right answer here.

  • ✓

    CALCULATE(COUNTROWS(Sales), DATESINPERIOD('Date'[Date], MAX('Date'[Date]), -30, DAY))

    Why this is correct

    This expression is correct because DATESINPERIOD constructs a continuous, dynamic 30-day window ending at the boundary defined by MAX('Date'[Date])—the latest date present in the current filter context. By specifying DAY as the interval type and a negative offset of -30, the function returns the set of dates from MAX('Date'[Date]) minus 29 days through MAX('Date'[Date]), inclusive of both endpoints, resulting in exactly 30 calendar days. Since it is anchored to the maximum date in the date table rather than to a hardcoded system date like TODAY(), it remains accurate even when the underlying data has not been refreshed up to the current day, and it automatically adapts to whatever date range is selected in a report slicer or page filter, making it the most robust choice for a rolling last-30-days measure.

  • ✗

    CALCULATE(COUNTROWS(Sales), DATESBETWEEN('Date'[Date], TODAY()-30, TODAY()))

    Why it's wrong here

    This expression is incorrect because DATESBETWEEN creates a fixed window from TODAY()-30 to TODAY(), which assumes both dates exist in the 'Date' table and that 'today' is the reference point for the desired period. In practice, the date table may only span through the last data load date, which could be earlier than the system's current date, causing the filter to evaluate over an empty or incomplete date set and produce a blank or understated result. Furthermore, this approach does not respect the filter context of a report—if a user filters to a specific historical month, the measure still ignores that selection and returns sales for the 30 days leading up to the real-world today, making it inconsistent for interactive analysis where the expected behavior is to show the trailing 30 days relative to the selected period's end date.

  • ✗

    CALCULATE(COUNTROWS(Sales), PREVIOUSMONTH('Date'[Date]))

    Why it's wrong here

    This expression is wrong because PREVIOUSMONTH returns the entire calendar month that precedes the month of the current filter context, not a rolling 30-day interval. For example, if the current context is May 2025, this function returns all dates from April 1 to April 30, regardless of whether the user is viewing a specific day, week, or year-to-date selection; the number of days can vary between 28 and 31, so it does not reliably represent a 30-day span. Additionally, PREVIOUSMONTH ignores the day-level granularity needed for a trailing window—it resets to month boundaries and cannot reflect the 30 days immediately preceding an arbitrary date such as the 15th of the month, making it inappropriate for any kind of 'last 30 days' metric.

  • ✗

    CALCULATE(COUNTROWS(Sales), DATEADD('Date'[Date], -30, DAY))

    Why it's wrong here

    This expression is incorrect because DATEADD with an offset of -30 days shifts the existing set of dates in the current filter context back by exactly 30 days, rather than isolating the trailing 30-day range ending at the maximum date. If the current filter context contains a single date, DATEADD returns only that one date shifted back by 30 days, which would count rows for just one day, not a 30-day window; if the context contains a full month or year, DATEADD returns that entire period shifted backward, producing a comparison of the same-length period shifted in time but not bounded by the latest date. This function is designed for period-over-period comparisons (e.g., comparing this month to the same month last year) and does not create the dynamic, end-anchored window that DATESINPERIOD provides.

About these practice questions

One of 524 original PL-300 practice questions on Courseiva, each with a full explanation and wrong-answer analysis — not exam dumps or protected exam content. Learn why practice questions differ from exam dumps →

How Courseiva writes practice questions · Editorial policy

JA

Written by Johnson Ajibi, MSc IT Security

Senior Network & Security Engineer · founder of Courseiva

This PL-300 practice question is part of Courseiva's free Microsoft certification practice question bank. Courseiva provides original exam-style practice questions with explanations, topic-based practice, mock exams, readiness tracking, and study analytics to help learners prepare for the PL-300 exam.