Hello! Welcome back to our journey into Target vs. Actual analysis.
In our last lesson, you did the essential groundwork by importing and modeling our Budget table. You now have a clean, robust data model where both the daily Sales data and the monthly Budget data are connected through shared DimDate and DimProduct dimension tables.
This setup leads us to a classic data analysis problem: our 'actuals' are recorded at a high granularity (daily), while our 'targets' are at a low granularity (monthly). How can we meaningfully compare a single day's sales against a budget set for an entire month?
Today, you will learn how to write DAX measures to bridge this granularity gap. By the end of this lesson, you will be able to handle these different levels of detail using two distinct and powerful professional techniques.
The Core Problem: Comparing Apples and Oranges
Let's start by creating a basic measure for our budget:
Total Budget = SUM(Budget[Budget])
Now, imagine you place this measure in a table visual with the DimDate[Date] column. For January 1st, the table would show the entire budget for all of January. For January 2nd, it would show that same large number again. This is not only incorrect but highly misleading, as it massively inflates the totals when viewed at a daily level.

To solve this, we will explore two strategies:
- The "Safe Display" Strategy: Ensuring the budget value is only shown when it's valid and not misleading.
- The "Allocation" Strategy: Distributing the monthly budget across the days to create a daily target.
Strategy 1: The "Safe Display" Method
This first strategy prioritizes accuracy and avoiding misinterpretation. The goal is to write a measure that shows the budget value only when the report is viewed at a level where the budget is defined (e.g., month, quarter, year) and returns a blank otherwise.
This prevents a user from seeing a repeated monthly budget value and thinking it applies to a single day. This is a fundamental pattern for writing robust DAX code.
The logic is simple: if we are looking at a single day, don't show the monthly budget. If we are looking at a level that includes all the days of a month (or multiple months), then it's safe to show the budget.
We can implement a basic version of this logic with the following DAX measure. HASONEVALUE(DimDate[Date]) returns TRUE only when a single date is visible in the current context (i.e., we are at the day level).
Budget (Safe) =
VAR IsAtDayLevel = HASONEVALUE(DimDate[Date])
RETURN
IF(
IsAtDayLevel,
BLANK(),
[Total Budget]
)
When you use this measure in a table with Date on the rows, it will correctly show blanks for individual dates but will calculate the total at the month and year levels. While more advanced patterns exist for complex scenarios, this approach effectively demonstrates the core principle: control when and where your values are displayed to ensure correctness.
Strategy 2: The Allocation Method
While the "Safe Display" method is great for preventing errors, business users often want to track daily progress. For that, we need to allocate the monthly budget down to a daily level.
The most common method is to assume an even distribution. The logic is straightforward:
Daily Allocated Budget = Total Monthly Budget / Number of Days in that Month
This creates a synthetic "daily budget" that can be directly compared against daily sales and which will correctly sum up to the total monthly budget. A fantastic, clear explanation of this technique is provided in the following video.
The Ultimate Budget Allocation Methodology For Power BI Analysis
The video 'The Ultimate Budget Allocation Methodology For Power BI Analysis' from Enterprise DNA provides a masterclass in this technique. It walks through the exact DAX logic needed to dynamically allocate a budget.
Please watch the following segments to understand the complete methodology: The Problem (00:37 - 01:45): The presenter explains the granularity mismatch between monthly budgets and daily sales. The Core Formula (02:46 - 04:15): The key allocation logic is revealed: Monthly Budget * (1 / Days in Month). Calculating Days in Month (05:36 - 06:59): See the DAX pattern used to dynamically count the number of days in the current month of the filter context. Putting It All Together (09:20 - 09:48): The final formula combining all the pieces is shown.
Let's break down how to build this measure in DAX, using variables for clarity, just as you learned is a best practice.
Allocated Budget =
VAR TotalBudget = [Total Budget] // Our base measure: SUM(Budget[Budget])
// This part dynamically calculates the number of days in the month
// currently visible in the filter context.
VAR DaysInMonth =
CALCULATE(
COUNTROWS(DimDate),
ALL(DimDate), // Removes all filters from the Date table...
VALUES(DimDate[YearMonthName]) // ...then adds back the filter for the current month.
)
VAR DailyAllocation = DIVIDE(TotalBudget, DaysInMonth)
RETURN
DailyAllocation
This [Allocated Budget] measure is incredibly powerful.
- At the day level, it shows the correctly allocated portion of the monthly budget.
- At the month level, the
SUMXlogic within Power BI visuals will correctly sum up all the daily allocations to equal the original total monthly budget. - It is dynamic, meaning it correctly handles months with 28, 29, 30, or 31 days.
Choosing Your Strategy
You've now seen two valid ways to handle granularity differences. Which one should you use?
- Use the "Safe Display" method when the business logic treats a budget as an indivisible monthly or quarterly goal. It's the most accurate representation of the source data and prevents any misinterpretation.
- Use the "Allocation" method when the business wants to monitor performance at a more granular level (like daily) and accepts the assumption that the target is spread evenly over the period. It provides a useful daily benchmark for operational tracking.
For our project, we will create both, as they serve different analytical purposes.
Your Turn: Create the Budget Measures
It's time to apply these patterns to our data model. Your task is to create the two key budget measures we've discussed.
Task 1: Create the "Safe Display" Budget Measure
- If you haven't already, create the base measure:
Total Budget = SUM(Budget[Budget]) - Create a new measure named
Budget (Monthly Grain)that returns the[Total Budget]only when the report is not at a day-level granularity. Otherwise, it should returnBLANK().- Hint: Use the
IF(HASONEVALUE(DimDate[Date]), ...)pattern we discussed.
- Hint: Use the
Task 2: Create the "Allocated" Budget Measure
- Create a new measure named
Allocated Budgetthat calculates and returns the daily allocated budget amount.- Hint: Follow the
VAR...RETURNstructure from the video and our breakdown. You'll need[Total Budget], a variable to calculateDaysInMonth, and a finalDIVIDEcalculation.
- Hint: Follow the
Click here to see the DAX solution for `Budget (Monthly Grain)`.
Budget (Monthly Grain) =
VAR IsAtDayLevel = HASONEVALUE(DimDate[Date])
RETURN
IF(
IsAtDayLevel,
BLANK(),
[Total Budget]
)
Click here to see the DAX solution for `Allocated Budget`.
Allocated Budget =
// Get the budget for the current filter context (e.g., for the current month).
VAR TotalBudgetForPeriod = [Total Budget]
// Count the number of days in the month of the current filter context.
VAR DaysInCurrentMonth =
CALCULATE(
COUNTROWS(DimDate),
ALL(DimDate), // Remove existing filters on the date table...
VALUES(DimDate[YearMonthName]) // ...and restore the filter for only the current month.
)
// Divide the total budget by the number of days to get the daily allocation.
VAR DailyAllocation = DIVIDE(TotalBudgetForPeriod, DaysInCurrentMonth)
RETURN
DailyAllocation
Conclusion
Fantastic work! You have now mastered one of the most common and important challenges in DAX: handling data at different granularities. You not only understand the problem but are equipped with two professional-grade solutions to solve it.
Key Takeaways:
- Granularity Mismatch: This is a standard problem where fact tables (like sales) and target tables (like budgets) have different levels of detail.
- "Safe Display" Strategy: Use conditional logic (like
IFandHASONEVALUE) to show measures only at their valid granularity, preventing misinterpretation by returningBLANK()at finer levels. - "Allocation" Strategy: Use DAX to mathematically distribute a coarse-grained value (monthly budget) across a finer grain (days). This is typically done by dividing the total by the number of periods within it (e.g.,
Total Budget / Days in Month).
Preview of the Next Lesson:
With our Sales and Budget measures now able to be compared on a level playing field, we are ready for the payoff. In our next lesson, you will write measures to calculate the absolute and percentage variance between actual sales and targets. This is where we start generating the core insights for our business stakeholders.