Companion content
Insert your email address and press Download for access to the files used in this book.Errata corrige
To ensure the ongoing accuracy of this book and its companion content, we have reviewed and confirmed the errors listed below. If you find a new oversight not included in both of the following sections, please report it to us.
Important issues
Corrections in this section are important to fully understand the concepts explained in the book.-
Page 476: Year is a bound column
In the paragraph after Figure 12-21, the description mention Year as an unbound column, while it is a bound column. The right sentence is:
The source table now contains three columns: Continent and Year are bound, whereas @Sales is unbound.
Feb 3, 2026
Minor issues
Corrections in this section do not affect the ability to learn the concepts explained in the book.-
Page 19: SUMX instead of SUM
The measure defined in the second line of the first code snipped should be SUMX instead of SUM. The correct first two lines are as follows:
DEFINE MEASURE Sales[Sales Amount] = SUMX ( Sales, Sales[Quantity] * Sales[Net Price] )Dec 20, 2025 -
Page 39: Gross Margin Pct should reference Sales[LineMargin]
The measure preceding Figure 2-7 should reference Sales[LineMargin] instead of Sales[GrossMargin].
The definition of Gross Margin Pct should be the following:Measure in Sales tableGross Margin Pct = SUM ( Sales[LineMargin] ) / SUM ( Sales[LineAmount] )
Jan 20, 2026 -
Page 57: Inaccurate calculation in the Occurrences measure
The implementation of the # Occurrences measure counts the number of keywords, not the number of products that contain at least one of the keywords mentioned.
A correct version of the calculation is the following:
# Occurrences = COUNTROWS ( FILTER ( 'Product', COUNTROWS ( FILTER ( Keywords, CONTAINSSTRING ( 'Product'[Product Name], Keywords[Keyword] ) ) ) > 0 ) )The only difference in the result is the Total, which is 900 instead of 943 for # Occurrences and 35.76% instead of 37.47% for Perc.
However, for the purpose of this initial introduction, this is a minor issue. The goal was to expose the syntax of two nested iterations that will be explained later in the book.
Jan 2, 2026 -
Page 61: Figure 2-20 description
The description in Figure 2-20 should reference “category” instead of “brand”. The correct description of Figure 2-20 is the following:
RELATEDTABLE returns all the products for each category.
Mar 2, 2026 -
Page 83: Figure 3-3 marker 2 should be close to 2018
The marker (2) in Figure 3-3 is close to “Female”, but it should be close to “2018” on the highlighted row.
Jan 23, 2026 -
Page 128: Sum instead of average
In the first paragraph of the page, immediately before Figure 4-15, the noun “average” should be “sum” in the second sentence, which should be read as follows:
Therefore, the value computed is the sum of all brands in the given year, …
Jan 8, 2026 -
Page 144: Measure for icon result
In the first paragraph of “Computing the icon” section, the result of the measure for the icon is -1, 0, or 1 instead of “1 or 2. Therefore, instead of:
We write a measure that returns 1 or 2 based on the sign…
The right sentence should be:
We write a measure that returns -1, 0, 0r 1 based on the sign…
Feb 3, 2026 -
Page 168: Figure 5-5 label correction
The Figure 5-5 label should say “two ore more products” instead of “more than two products”. The correct label is:
FIGURE 5-5 # Good Customers shows the customers who bought two or more products.Jan 4, 2026 -
Page 172: Net Price should be Unit Price column reference in code snippet
The code snippet iterates Product[Net Price] instead of Product[Unit Price]. The right code snippet should be as follows:
SUMX ( VALUES ( 'Product'[Unit Price] ), IF ( 'Product'[Unit Price] >= 10, 'Product'[Unit Price] * [Sales Amount] ) )Jan 4, 2026 -
Page 174: Remove Sales[Quantity] from Amount variable assignment expression
The Amount variable in the code snippet should be assigned to Sales[Net Price] without being multiplied by Sales[Quantity].
The right code snippet is the following:Avg Amt per Kg = AVERAGEX ( Sales, VAR Amount = Sales[Net Price] VAR NormalizedWeight = SWITCH ( RELATED ( 'Product'[Weight Unit Measure] ), "ounces", 0.0283495, "grams", 0.001, "pounds", 0.453592 ) * RELATED ( 'Product'[Weight] ) VAR Result = DIVIDE ( Amount, NormalizedWeight ) RETURN Result )Jan 13, 2026 -
Page 182: Use ‘Product'[FirstSale] instead of ‘Product'[First Sale]
In the third line of the code snipped for the measure in the Sales table, use ‘Product'[FirstSale] instead of ‘Product'[First Sale]. The right code is as follows:
First Week Sales = SUMX ( VALUES ( 'Product'[FirstSale] ), VAR FirstSale = 'Product'[FirstSale] RETURN CALCULATE ( [Sales Amount], Sales[Order Date] >= FirstSale && Sales[Order Date] < FirstSale + 7 ) )Jan 27, 2026 -
Page 187: Missing comma after RELATEDTABLE ( Sales )
There is a missing comma at the end of RELATEDTABLE ( Sales ) on the sixth row of the code example.
SUMX ( 'Product Category', -- Scans the Product Category table SUMX ( -- For each category RELATEDTABLE ( 'Product' ), -- Scans the products SUMX ( -- For each product RELATEDTABLE ( Sales ), -- Scans the sales of that product Sales[Quantity] -- * 'Product'[Unit Price] -- Computes the sales amount of that sale * 'Product Category'[Discount] ) ) )Jan 27, 2026 -
Page 226: SUMMARIZECOLUMNS instead of ADDCOLUMNS and SUMMARIZE
In the first paragraph of the “Computing the best store by product” section, use SUMMARIZECOLUMNS instead of “ADDCOLUMNS and SUMMARIZE working together”.
The right sentence is:[…] let us look at an example of SUMMARIZECOLUMNS to solve a non-trivial scenario. […]
Feb 3, 2026 -
Page 230: Use Product[Brand] instead of Product[Color] after Figure 6-26
In the paragraph after Figure 6-26, use Product[Brand] as a column reference instead of Product[Color]. The right sentence should be:
The Brand Name measure uses COUNTROWS to check whether Product[Brand] has only one value visible in the current filter context.
Jan 26, 2026 -
Page 235: Remove “expanded” from “of the same expanded table” sentence.
In the last sentence of the page, just before the Conclusions section of Chapter 6, the word “expanded” must be eliminated from “of the same expanded table,” resulting in “of the same table”. The right sentence is:
ALLSELECTED proves particularly useful. You can use as arguments of ALLSELECTED a table or a list of columns of the same table, or no parameters at all.
Jan 28, 2026 -
Page 240: Remove ‘)’ after Sales[CustomerKey]
In both code snippets of the page (first two code snippets of “The importance of variable names” section), there is a bracket ‘)’ after Sales[CustomerKey] that should be removed.
Instead of:
Sales[CustomerKey] ),The code should be:
Sales[CustomerKey],Feb 3, 2026 -
Page 256: Figure 8-1 filters Product[Color] instead of Sales[Net Price]
In Figure 8-1, the filter is on Product[Color] instead of Sales[Net Price].
The correct DAX Code is the following:CALCULATE ( [Sales Amount], 'Product'[Color] = "Red" )Feb 5, 2026 -
Page 270: Typo in Figure 8-14
The Row result or “Row 2” in Figure 8-14 should be 54.95 instead of 57.95.
Feb 7, 2026 -
Page 281: Outer row context instead of outer filter context before Figure 8-20
In the last paragraph of the page, the one preceding Figure 8-20 in the following page, the reference to the “outer filter context” should be to the “outer row context”. The correct sentence is:
[…] the value of Date[Year] is taken from the outer row context […]
Jan 30, 2026 -
Page 289: Clarification about context transition
At the end of the second paragraph in the section “Leveraging context transition in iterators” (which is the last sentence at page 289), the reference to the algorithm without context transition is inaccurate, because RELATEDTABLE internally is a CALCULATETABLE that works with a context transition. The following sentence:
We will first show the algorithm without using the context transition and then make it better by leveraging the context transition.
Should be rephrased as follows:
We will first show the algorithm using table stored in a variable and then make it better by leveraging the context transition.
Feb 7, 2026 -
Page 297: CROSSFILTER instead of USERELATIONSHIP
In the paragraph before Figure 8-28, instead of USERELATIONSHIP, the function should be CROSSFILTER (as correctly stated in the following paragraphs). The correct sentence is:
Despite the model’s unidirectional relationship between Product and Sales, as shown in Figure 8-28, USERELATIONSHIP can change the cross-filter direction and make it bidirectional.
Jan 24, 2026 -
Page 308: Use Sales[Net Price] instead of Sales[Unit Cost]
The two calculated columns MarginPct and Margin should reference Sales[Net Price] instead of Sales[Unit Cost].
The right definition is as follows:
Calculated columns in Sales tableMarginPct = DIVIDE ( Sales[Margin], Sales[Net Price] ) Margin = Sales[MarginPct] * Sales[Net Price]
Feb 16, 2026 -
Page 376: Parameter name mismatch in RangeLookup function
The parameters used in the function RangeLookup have name different from the parameters: colMin, colMax, and colTarget should be minColumn, maxColumn, and targetColumn, respectively.
The correct complete definition is the following:Function definitionRangeLookup = ( search : SCALAR VAL, lookupTable : ANYREF EXPR, minColumn : ANYREF EXPR, maxColumn : ANYREF EXPR, targetColumn : ANYREF EXPR ) => SELECTCOLUMNS ( FILTER ( lookupTable, minColumn <= search && maxColumn > search ), "@Result", targetColumn )Feb 7, 2026 -
Page 433: CROSS APPLY instead of OUTER APPLY
In the first sentence of the “Using GENERATE and GENERATEALL” section, the reference to OUTER APPLY should be replaced by CROSS APPLY, which describes the logic of GENERATE, while OUTER APPLY describes the logic of GENERATEALL. A better version of the first sentence is the following one:
GENERATE is a powerful function that implements the
OUTER APPLYCROSS APPLY logic from the SQL language, while GENERATEALL implements the OUTER APPLY logic.Feb 4, 2026 -
Page 470: Customer[Name] instead of Sales[Order Date]
In the paragraph before Figure 12-16, the column reference to Sales[Order Date] should be to Customer[Name]. The right sentence is:
OFFSET creates its source table using SUMMARIZE, which returns Customer[Name] and Sales[Order Number].
Feb 3, 2026 -
Page 471: Incorrect table headers in Figure 12-17
The Sales and Product table headers in Figure 12-17 should be removed from the figure, they are unrelated to the content displayed.
Nov 25, 2025 -
Page 487: Reference to SUMX instead of CALCULATE
The first paragraph on the page, immediately after Figure 12-31 in the previous page, has a reference to SUMX that is not present in the code executed for Figure 12-31.
At the beginning of the paragraph, instead of:
This behavior occurs because the context transition executed by SUMX while iterating over the
result of WINDOW is not overriding the outer filter context generated by SUMMARIZECOLUMNS.The correct sentence should be the following:
This behavior occurs because the filter context applied by CALCULATE with WINDOW does not override the filter context generated by SUMMARIZECOLUMNS.
Feb 3, 2026 -
Page 491: Missing assignment operator in DAX measure
There is a missing “=” assignment operator after the line
VAR Resultin the 6 Months Avg measure. The correct code of the final part of the 6 Months Avg measure should be:VAR Result = IF ( [Sales Amount] > 0, MovingAverage ) RETURN ResultNov 25, 2025 -
Page 502: PARTITIONBY instead of ORDERBY in last sentence
In the last sentence of the last paragraph, which is the paragraph after prevExchange 2 calculated column definition, the function ORDERBY should be PARTITIONBY. The correct sentence is:
Two are specified in the PARTITIONBY section, and the third is specified in the
MATCHBY section.Feb 3, 2026 -
Page 515: In Figure 13-2, year is 2018
The filter for Date[Year] in Figure 13-2 should be 2018 instead of 2017 for both “Cell filter context” and “Active filters”.
Mar 1, 2026 -
Page 522: DateTime instead of DateType
In the third bullet point of “Building a date” table section, there is a reference to DateType that should be DateTime. The correct sentence is:
[…] (even though the physical column internally remains of type DateType). […]
Feb 3, 2026 -
Page 556: DATESINPERIOD instead of PARALLELPERIOD
In the first line of the last paragraph of the page (before Figure 13-30), the sentence should reference DATESINPERIOD instead of PARALLELPERIOD.
The right version is: “The second argument of DATESINPERIOD is the reference date, …”Jan 7, 2026 -
Page 568: Comparison in FirstDateWithTransactions function
The FirstDateWithTransactions function defined in the “TMLD definition for function” snippet should use “>=” instead of “<=” as a comparison between dateColumn and FirstVisibleDate. The right assignment of the FirstDateWithData variable is the following:
VAR FirstDateWithData = CALCULATE ( MIN ( dateTransaction ), KEEPFILTERS ( dateColumn <= FirstVisibleDate ) )Feb 18, 2026 -
Page 608: Internal note to ignore in Figure 14-38
The note ** insert F14xx38 no crop on the top of Figure 14-38 should be ignored, it is an internal editing note that was left in production by mistake.
Jan 9, 2026 -
Page 619: Figure 14-50 description
The correct description for Figure 14-50 should be the following:
Figure 14-50 The Monthly Moving Average computes the average of the full month also at the day level.
Feb 3, 2026 -
Page 684: Use ISINSCOPE instead of ISFILTERED
The definition of the ParentChild calculation item should use ISINSCOPE instead of ISFILTERED. The correct code is the following:
Calculation groupCALCULATIONGROUP ParentChild[Hide unwanted rows] CALCULATIONITEM "ParentChild" = VAR BrowseDepth = ISINSCOPE (Persons[Level1]) + ISINSCOPE (Persons[Level2]) + ISINSCOPE (Persons[Level3]) VAR MaxDepth = MAX ( Persons[NodeDepth] ) VAR Result = IF ( MaxDepth >= BrowseDepth, SELECTEDMEASURE () ) RETURN ResultFeb 3, 2026 -
Page 717: Year column in Figure 18-1
The table SalesDeliveryDate in Figure 18-1 should have 2018 instead of 2017 in the second and third row of the column Year (the year should correspond to the Date column).
Feb 22, 2026 -
Page 741: Figure 18-18 description
The description for Figure 18-18 references Date instead of Product. The correct description is the following:
FIGURE 18-18 When the bidirectional cross-filter is enabled between Sales and Product, the filter will now propagate from Customer to Product.
Feb 3, 2026 -
Page 746: Typo in Rec Amt CF REMOVEFILTERS measure name
In the first line of the paragraph before Figure 18-25, the measure referenced should be Rec Amt REMOVEFILTERS instead of Rec Amt CF REMOVEFILTERS. The right start of the paragraph is:
In the other measure, Rec Amt REMOVEFILTERS, we have a version […]
Feb 3, 2026 -
Page 764: Date instead of MonthlyBudget in one reference
The last paragraph of the page include a sentence with a reference to MonthlyBudget that should be Date. Here is the complete sentence, with the correction shown after the struck-through MonthlyBudget reference.
[..] MonthlyBudget depends on the presence of a blank row because it uses column values from
MonthlyBudgetDate, and BLANK is one of the many possible values. […]Feb 3, 2026 -
Page 768: Categories instead of brand
The last sentence in the paragraph before Figure 19-6 references “brands” instead of “categories”. Here is the complete sentence, with the correction shown after the struck-through brands reference:
Summing the
brandscategories in Canada would produce a budget much larger than the total displayed for Canada.Feb 3, 2026 -
Page 794: Code in the book not aligned to the code in the sample file
The code of the Open Stores Amount 2 measure is inaccurate, the definition of the AllStoreStatuses variable does not include the correct column @OpenYears filtered in OpenStores; the sample file contains the correct code, which is the following:
Measure in Sales tableOpen Stores Amount 2 = VAR AllSelectedYears = CALCULATETABLE ( SUMMARIZECOLUMNS ( 'Date'[Year], "@", COUNTROWS ( StoreStatus ) ), ALLSELECTED ( 'Date' ), ALLSELECTED ( 'Product' ), ALLSELECTED ( Store ) ) VAR NumberOfYears = COUNTROWS ( AllSelectedYears ) VAR AllStoreStatuses = SUMMARIZECOLUMNS ( Store[StoreKey], 'Product'[Category], "@OpenYears", CALCULATE ( COUNTROWS ( StoreStatus ), ALLSELECTED ( 'Date' ), StoreStatus[Status] = "Open" ) ) VAR OpenStores = SELECTCOLUMNS ( FILTER ( AllStoreStatuses, [@OpenYears] == NumberOfYears ), Store[StoreKey], 'Product'[Category] ) VAR Result = CALCULATE ( [Sales Amount], KEEPFILTERS ( OpenStores ) ) RETURN ResultJan 14, 2026