Hi all,
I have created a complex DAX measure that runs on a filtered dataset but becomes unusable on the full dataset. The calculations are accurate, but I need to optimize it for performance.
The Problem
Here is the error I get when trying to run it on the full dataset:
However, when I use some filters, it works as intended:
In the screenshot above, the numbers on the side represent customer ids. The numbers in the values section of the matrix are indicators showing when a customer is counted in the âbeginning balanceâ or ânew saleâ, etc.
The matrix acts as a type of ledger table that tracks when a customer is considered active or inactive.
Begin Balance means that a customer is active as of the first of the month.
New Start means that a customer became a new member or returning member during that month.
Canceled and Expired indicate that a customer is no longer active within that month.
End balance means that the customer is active as of the end of the month.
The ledger works by the following formula
Begin Balance + New Start - Canceleld - Expired = End Balance.
Each measure is built similarly so I will choose the Expired measure since it is the most complex
.
Model and Sample Data:
Here is a screenshot of my model:
The relationships are as follows:
Branch Service Agreements by Customer
Branch Sk 1:* Branch Sk
Agreement Event Type Service Agreements by Customer
Agreement Event Type Sk 1:* Agreement Event Type Sk
Location Service Agreements by Customer
Location Sk 1:* Location Sk
Here is a sample of what the Service Agreements by Customer data looks like:
Location Sk | Service Agreement Sk | Branch Sk | Agreement Event Type Sk | Offset Agreement Start Date | Agreement Begin Date | Agreement Expired Or Canceled Date | Agreement End Date | Previous Agreement Expired Or Canceled Date | Location Sk - Copy | Service Agreement Id | Previous Service Agreement Id | Future Agreement Start Date |
---|---|---|---|---|---|---|---|---|---|---|---|---|
7707 | 1270133 | 54 | 5 | 1/7/2023 | 1/8/2022 | 4/8/2023 | 1/8/2023 | 7707 | 1308929 | 1/7/2023 | ||
7707 | 1356440 | 54 | 6 | 1/7/2023 | 4/6/2024 | 1/7/2024 | 4/8/2023 | 7707 | 1395552 | 1308929 | ||
12864 | 1268235 | 37 | 4 | 11/8/2022 | 5/11/2023 | 5/11/2023 | 12864 | 1304419 | ||||
12874 | 1266588 | 41 | 6 | 11/6/2022 | 2/4/2024 | 11/6/2023 | 12874 | 1304024 |
DAX Code Summary
Here is a summary of the code. Thanks to Chat GPT
Variables
- MaxDate: Calculates the maximum date in the Calendar table.
- CurrentMonthStart: Finds the first day of the month based on MaxDate.
- CurrentMonthEnd: Finds the last day of the month based on MaxDate.
- AgreementsByCustomer: Creates a summarized table from the âService Agreements by Customerâ table. It includes columns like Location Sk, Agreement Event Type Sk, Agreement Begin Date, and Agreement Expired Or Canceled Date. It also removes any filters on the Calendar table and excludes rows where Location Sk is blank.
- PreviousAgreements: Filters AgreementsByCustomer to only include agreements that both started and expired or were canceled before the start of the current month.
- CurrentAgreements: Filters AgreementsByCustomer to only include agreements that expire or are canceled within the current month and have an Agreement Event Type Sk of 5.
- FutureAgreements: Filters AgreementsByCustomer to only include agreements that will expire or be canceled after the current month ends.
Additional Calculations
- IterationTable: Adds two new columns to CurrentAgreements:
- PreviousActiveAgreement: Checks if there are any previous agreements for the same location that expired or were canceled on or after the current agreementâs expiration or cancellation date.
- FutureActiveAgreement: Checks if there are any future agreements for the same location that begin before the current agreementâs expiration or cancellation date.
- FilterTable: Filters IterationTable to only include rows where both PreviousActiveAgreement and FutureActiveAgreement are 0 (i.e., there are no overlapping previous or future agreements).
Final Output
- Result: Counts the number of unique Location Sk in FilterTable.
- RETURN Result: Returns the final count as the output of the DAX expression.
DAX Code:
Expired =
VAR MaxDate =
CALCULATE ( MAX ( Calendar[Calendar Date] ), ( Calendar ) )
VAR CurrentMonthStart =
EOMONTH ( MaxDate, -1 ) + 1
VAR CurrentMonthEnd =
EOMONTH ( MaxDate, 0 )
VAR AgreementsByCustomer =
CALCULATETABLE (
SUMMARIZE (
'Service Agreements by Customer',
'Service Agreements by Customer'[Location Sk],
'Service Agreements by Customer'[Agreement Event Type Sk],
'Service Agreements by Customer'[Agreement Begin Date],
'Service Agreements by Customer'[Agreement Expired Or Canceled Date]
),
ALL ( Calendar ),
NOT ISBLANK ( 'Service Agreements by Customer'[Location Sk] )
)
VAR PreviousAgreements =
FILTER (
AgreementsByCustomer,
'Service Agreements by Customer'[Agreement Begin Date] < CurrentMonthStart
&& 'Service Agreements by Customer'[Agreement Expired Or Canceled Date] < CurrentMonthStart
)
VAR CurrentAgreements =
FILTER (
AgreementsByCustomer,
'Service Agreements by Customer'[Agreement Expired Or Canceled Date] >= CurrentMonthStart
&& 'Service Agreements by Customer'[Agreement Expired Or Canceled Date] <= CurrentMonthEnd
&& 'Service Agreements by Customer'[Agreement Event Type Sk] = 5
)
VAR FutureAgreements =
FILTER (
AgreementsByCustomer,
'Service Agreements by Customer'[Agreement Expired Or Canceled Date] > CurrentMonthEnd
)
VAR IterationTable =
ADDCOLUMNS (
CurrentAgreements,
"PreviousActiveAgreement",
VAR CurrentAgreementExpired = 'Service Agreements by Customer'[Agreement Expired Or Canceled Date]
VAR LocationSk = 'Service Agreements by Customer'[Location Sk]
VAR PreviousActiveAgreements =
FILTER (
PreviousAgreements,
'Service Agreements by Customer'[Location Sk] = LocationSk
&& 'Service Agreements by Customer'[Agreement Expired Or Canceled Date] >= CurrentAgreementExpired
)
RETURN
IF ( COUNTROWS ( PreviousActiveAgreements ) = 0, 0, 1 ),
"FutureActiveAgreement",
VAR CurrentAgreementExpired = 'Service Agreements by Customer'[Agreement Expired Or Canceled Date]
VAR LocationSk = 'Service Agreements by Customer'[Location Sk]
VAR FutureActiveAgreement =
FILTER (
FutureAgreements,
'Service Agreements by Customer'[Location Sk] = LocationSk
&& IF (
ISBLANK ( 'Service Agreements by Customer'[Agreement Begin Date] ),
FALSE (),
'Service Agreements by Customer'[Agreement Begin Date] < CurrentAgreementExpired
)
)
RETURN
IF ( COUNTROWS ( FutureActiveAgreement ) >= 1, 1, 0 )
)
VAR FilterTable =
FILTER (
IterationTable,
[PreviousActiveAgreement] = 0
&& [FutureActiveAgreement] = 0
)
VAR Result =
COUNTROWS (
SUMMARIZE ( FilterTable, 'Service Agreements by Customer'[Location Sk] )
)
RETURN
Result