Chapter 14: Data Models and DAX Measures

Accounting Analytics: An Integrated Approach

In this chapter

Part IV of V: Data Visualization and Power BI

Chapter 2 of 4 in this Part

  • 14.1 From Tables to a Model
  • 14.2 Relationships
  • 14.3 The Date Table
  • Guided Tutorial 14.1
  • 14.5 Measures and Calculated Columns
  • 14.6 Evaluation Context
  • 14.7 CALCULATE
  • 14.8 Testing Measures in DAX Query View
  • Guided Tutorial 14.2
  • 14.10 Time Intelligence
  • 14.11 Modeling the General Ledger
  • Guided Tutorial 14.3
  • 14.13 Looking Ahead

Learning objectives

  1. Design a star schema from the Charles River tables, naming its fact and dimension tables and its grain, and flatten a header-line pair into one fact table.
  2. Build and mark a date table, set the cardinality and cross filter direction of relationships, and use an inactive relationship for a second date.
  3. Write explicit measures with SUM, DIVIDE, SUMX, RELATED, and variables, and choose between a measure, a DAX calculated column, and a Power Query column.

Learning objectives (continued)

  1. Explain filter context, row context, and context transition, and change the filter context with CALCULATE.
  2. Compare periods with time intelligence functions.
  3. Model the general ledger so that year-end closing entries and debit and credit signs are handled correctly, and test measures in DAX query view against control totals.

The report’s questions have outgrown it

  • The sales manager asks what the autumn discounts cost in margin
  • The marketing manager wants each month against the year before
  • A product manager asks which of two invoice counts is right
  • The controller wants the income statement there, tied to the ledger

14.1 From Tables to a Model

A star schema separates facts from dimensions

  • A fact table records events: one row each, with keys and amounts
  • A dimension table describes one kind of thing, with its attributes
  • Each dimension relates to the fact table on its key
  • The grain, the event one row represents, decides what a table can answer

The fact tables of this Part and their grain

Table 14.1 · Fact tables of the Charles River reports, with their grain and dimensions

Fact table Grain: one row for each Dimensions Chapter
SalesInvoiceLine line of an invoice Item, Customer, Date 13, 14
GLEntry posting to an account Account, CostCenter, Date 14
BudgetLine month, account, cost center, and item Account, CostCenter, Date 15
LaborTimeEntry time entry of an employee Employee, WorkCenter, Date 15
ProductionCompletionLine item line of a completion Item, Date 15
JournalEntry, PurchaseOrder, PayrollRegister document tested for exceptions Employee, Date 16
Exceptions exception of one test on one document Tests, Employee, Date 16

Chapter 13’s model was a snowflake

Detail of: Two diagrams of the sales tables, one above the other. Above, the model of Chapter 13: Customer relates to SalesInvoice, which relates to SalesInvoiceLine, and Item relates to SalesInvoiceLine, so Customer reaches the lines only through the invoice header. Below, the star: SalesInvoiceLine at the center carries the invoice number, invoice date, and customer key, shaded as the columns merged from the header, and Item, Customer, and Date each relate to it directly, many to one, with arrows pointing toward the lines.
Figure 14.1 · The Sales Tables as a Snowflake and as a Star (detail)

Flatten the header into the lines

Detail of: Two diagrams of the sales tables, one above the other. Above, the model of Chapter 13: Customer relates to SalesInvoice, which relates to SalesInvoiceLine, and Item relates to SalesInvoiceLine, so Customer reaches the lines only through the invoice header. Below, the star: SalesInvoiceLine at the center carries the invoice number, invoice date, and customer key, shaded as the columns merged from the header, and Item, Customer, and Date each relate to it directly, many to one, with arrows pointing toward the lines.
Figure 14.1 · The Sales Tables as a Snowflake and as a Star (detail)

14.2 Relationships

Cardinality and direction decide how filters travel

  • A star is built from many-to-one relationships, fact to dimension
  • One to one usually means two tables that are really one
  • Many to many signals a missing table in between
  • Single: a filter flows from the one side to the many; Both: both ways

Watch out: Both can look like a fix

  • A two-way filter makes a number change when you click
  • Check what the number now means before you accept it
  • With two fact tables, a selection can cross into the other one
  • Keep Single unless you can say in one sentence why not

An inactive relationship waits for USERELATIONSHIP

  • Only one path of relationships between two tables can be active
  • A second date, such as the ship date, gets an inactive relationship
  • It is drawn dashed and filters nothing on its own
  • A measure switches it on with USERELATIONSHIP

Check your understanding

Which setting does each need?

  1. The invoice lines and the Item table
  2. Two tables with exactly one row of each per key
  3. A second date that shares the same calendar
  4. An invoice count that ignores a selection on Item

Each one has its setting

  1. Many to one, with a single direction
  2. A second look: they may be one table
  3. An inactive relationship, used with USERELATIONSHIP
  4. Not Both: count the attribute on the fact table

14.3 The Date Table

One calendar for every fact table

  • One row for every day, with year, quarter and month columns
  • Unique dates, no blanks, no missing days, and full years
  • Built in DAX with CALENDAR, inside ADDCOLUMNS
  • Marked as the date table, which classic time intelligence needs

Watch out: ‘Date’ and ‘Item’ are reserved words

  • Write the date table as ‘Date’ and the item table as ‘Item’
  • An unquoted reserved name fails with a syntax error
  • Every visual that uses the broken measure shows an error
  • The suggestion list adds the quotes for you

Guided Tutorial 14.1: Building the Sales Star and the Date Table

Rebuild the model as a star in eight steps

  1. Merge the invoice header into the lines
  2. Create the date table
  3. Sort the month names and mark the date table
  4. Replace the relationships
  5. Point the visuals at the date table
  6. Stop loading SalesInvoice
  7. Hide the keys
  8. Reconcile the restructured model

The date table: one row for every day

Detail of: A mock of Power BI's Table view showing the first rows of the Date table: one row per day from January 1, 2024, with the columns Date, Year, Quarter, YearQuarter, YearMonth, MonthNumber, and MonthName. The status bar reports the table's name and number of rows, one for every day of four full years, and outlines it.
Figure 14.2 · The Date Table in Table View (detail)

Checkpoint

Before you write measures on the new model, confirm the following:

  • The model view shows SalesInvoiceLine related to Item, Customer, and Date, each many to one with a single direction, and SalesInvoice is no longer a table of the model.
  • The Date table is marked as the date table and has one row per day for four full years, with MonthName sorted by MonthNumber.
  • No visual shows an error, and the Validation page’s totals equal those of Tutorial 13.1.

14.5 Measures and Calculated Columns

A measure is calculated for every cell

  • An explicit measure is a named calculation, written in DAX
  • It is calculated from the rows that each cell’s filters keep
  • Revenue is one sum in a card and one for each cell of a matrix
  • It has a name, a format, and can be used inside other measures

Column or measure?

  • A calculated column is evaluated once per row at refresh, and stored
  • A measure is evaluated when a visual asks, and its result is not stored
  • A row’s own value to slice by is a column; a total or ratio, a measure
  • A column computable from its own row belongs in Power Query

14.6 Evaluation Context

A cell’s row and column become its filters

Detail of: A matrix of revenue by item group and quarter with the Furniture 2026-Q4 cell outlined, and an arrow to the filters that cell carries: ItemGroup equals Furniture on the Item table and YearQuarter equals 2026-Q4 on the Date table. Arrows carry the two filters along the relationships to the SalesInvoiceLine table, where only the Furniture lines invoiced in the fourth quarter of 2026 remain, and SUM of LineTotal adds them to the value shown in the cell.
Figure 14.3 · The Filter Context of One Matrix Cell (detail)

An iterator works row by row

Standard Cost =
SUMX (
    SalesInvoiceLine,
    SalesInvoiceLine[Quantity]
        * RELATED ( 'Item'[StandardCost] )
)
  • SUMX evaluates the expression for each line and adds the results
  • RELATED follows the line’s relationship to its one item

CALCULATE turns the current row into a filter

Detail of: Two calculated columns on the Customer table for the three customers with the most revenue. The column defined with SUM alone shows the same grand total of all invoice lines on every row. The column defined with CALCULATE around the same SUM shows each customer's own revenue, because CALCULATE turned the current row into a filter on Customer that the relationship carried to the invoice lines.
Figure 14.4 · Row Context With and Without Context Transition (detail)

Watch out: context transition filters every column

  • It filters on every column of the current row
  • On a dimension with a unique key, that picks out one row
  • On a table whose rows repeat, it picks out every identical row
  • Use measures inside iterators over dimensions, or unique rows

Check your understanding

Which context applies, and what is the result?

  1. A matrix cell for Furniture in one quarter
  2. SUMX over the invoice lines
  3. SUM in a calculated column on Customer
  4. The same SUM wrapped in CALCULATE

Each one has its context

  1. Filter context: the row and column filter the lines
  2. Row context: one line at a time, then added up
  3. Row context alone: every row shows the grand total
  4. Context transition: each customer’s own revenue

14.7 CALCULATE

CALCULATE replaces one filter or removes one

Furniture Revenue =
CALCULATE ( [Revenue], 'Item'[ItemGroup] = "Furniture" )

Share of Revenue =
DIVIDE (
    [Revenue],
    CALCULATE ( [Revenue], REMOVEFILTERS ( 'Item' ) )
)
  • A filter argument replaces any filter on the same column
  • REMOVEFILTERS drops the item filter and keeps every other one

Removing the right filter keeps the year

Detail of: A mock of a Power BI table visual with the item groups as rows and a year slicer set to 2026. The Revenue column shows each group's revenue. The Furniture Revenue column shows the same Furniture amount on every row, because its filter replaces the row's item group. The Share of Revenue column shows each group's share of fiscal 2026, adding up to 100 percent, with Furniture holding more than half. A note beside it shows that removing the filters from the whole invoice line table instead would reduce Furniture's share to about a fifth.
Figure 14.5 · A Filter That Replaces and a Filter That Is Removed (detail)

Habits that make measures reliable

  • DIVIDE returns a blank, not an error, when the denominator is zero
  • Filter on columns, not by iterating a whole table with FILTER
  • VAR and RETURN name an intermediate result, evaluated once
  • KEEPFILTERS combines a filter with the existing one

The DAX functions of this chapter

Table 14.3 · DAX functions used in this chapter

Function What it does Example in this chapter
SUM Adds up a column over the rows in the filter context Revenue
DISTINCTCOUNT Counts the different values of a column Invoices
DIVIDE Divides, returning a blank when the denominator is zero Margin %
SUMX Evaluates an expression row by row and adds the results Standard Cost
RELATED Returns a value from the one side of a relationship Standard Cost

The DAX functions of this chapter (continued)

Table 14.3 · DAX functions used in this chapter

Function What it does Example in this chapter
CALCULATE Evaluates an expression in a modified filter context Furniture Revenue
REMOVEFILTERS Removes filters from a table or column inside CALCULATE Share of Revenue
USERELATIONSHIP Activates an inactive relationship inside CALCULATE Revenue by ship date
VAR, RETURN Name an intermediate result and use it Margin %

14.8 Testing Measures in DAX Query View

A measure is tested against a total you trust

  • DAX query view runs queries and shows the result in a grid
  • A query is EVALUATE and a table, such as SUMMARIZECOLUMNS
  • The grid ignores formats, so tests round amounts to the cent
  • A Tests tab, saved with the report in Desktop, reruns every check

Test 1 is a query saved on a Tests tab

Detail of: A mock of DAX query view in Power BI Desktop. A tab named Tests holds a query with a comment line, EVALUATE, and SUMMARIZECOLUMNS grouping by the year of the Date table with the number of invoice lines, revenue, gross margin, and margin percentage. Below the editor, the results grid shows one row for each of fiscal 2024, 2025, and 2026, and the fiscal 2026 revenue is outlined because it must equal Chapter 6's control total.
Figure 14.6 · A Test in DAX Query View (detail)

Its result must equal Chapter 6

Detail of: A mock of DAX query view in Power BI Desktop. A tab named Tests holds a query with a comment line, EVALUATE, and SUMMARIZECOLUMNS grouping by the year of the Date table with the number of invoice lines, revenue, gross margin, and margin percentage. Below the editor, the results grid shows one row for each of fiscal 2024, 2025, and 2026, and the fiscal 2026 revenue is outlined because it must equal Chapter 6's control total.
Figure 14.6 · A Test in DAX Query View (detail)

Guided Tutorial 14.2: Writing and Testing the Margin Measures

Write and test the measures in nine steps

  1. Create a table for the measures
  2. Write the base measures
  3. Write the standard cost and the margin
  4. Write the discount rate
  5. Use CALCULATE to fix one filter and remove another
  6. Show Furniture’s margin by quarter
  7. Write the first test
  8. Write the second test
  9. Document the measures

Margin % is a ratio of totals

Gross Margin = [Revenue] - [Standard Cost]

Margin % =
VAR Rev = [Revenue]
RETURN
    DIVIDE ( Rev - [Standard Cost], Rev )

Discount Rate =
DIVIDE ( [Discounts], [Price Before Discount] )
  • The two ratios divide one total by another, which no implicit measure can do

Furniture’s margin fell in the last two quarters

Detail of: A mock of a Power BI matrix with the item groups as rows, the quarters of fiscal 2025 and 2026 as columns, and the margin percentage at standard cost in each cell, with a total row and a total column. The Furniture row is outlined: its margin holds within a narrow band from the first quarter of 2025 to the second quarter of 2026, slips in the third quarter, and falls clearly below the band in the fourth quarter of 2026.
Figure 14.7 · Margin at Standard Cost by Item Group and Quarter (detail)

Checkpoint

Your model should now pass these checks:

  • The Key Measures table holds the sales measures, each with a format and a description, and appears at the top of the Data pane.
  • Test 1’s fiscal 2026 row equals Chapter 6’s control totals, and Test 2 reproduces the Furniture margins at the two ends of Chapter 6’s bridge.
  • Discount Rate is higher than the Average of Discount of Chapter 13, and Share of Revenue adds up to 100% across the item groups of a year, though the rounded shares can add up to a hundredth more or less.

14.10 Time Intelligence

Time intelligence shifts or extends the dates

Table 14.4 · Time intelligence functions of this Part and where they are used

Function Returns, for the dates in the filter context Used in
TOTALYTD A measure’s total for the year to date, from January 1 unless another year-end is given Revenue YTD, Exercise 14.3
SAMEPERIODLASTYEAR The same dates one year earlier Revenue PY, Exercise 14.3
DATEADD The dates shifted by a number of days, months, quarters, or years The prior quarter, Exercise 14.4
DATESBETWEEN The dates between two dates, inclusive The three months before, Tutorial 14.3
DATESINPERIOD A period of a given length ending on a date The trailing twelve months, Chapter 15

The prior year, and its limits

  • CALCULATE ( [Revenue], SAMEPERIODLASTYEAR ( 'Date'[Date] ) )
  • The first year has no prior year, so DIVIDE leaves the change blank
  • The date table’s empty last year still has a prior year
  • So filter a prior-year visual to the years with data

Check your understanding

Which function does each comparison need?

  1. A month against the same month a year earlier
  2. The total from January to the current month
  3. The quarter before the current one
  4. The three months before a month, not including it

Each comparison has its function

  1. SAMEPERIODLASTYEAR
  2. TOTALYTD
  3. DATEADD, shifted back one quarter
  4. DATESBETWEEN

14.11 Modeling the General Ledger

The ledger is a second star sharing the Date table

Detail of: A mock of Power BI's Model view with two stars. On the left, SalesInvoiceLine is related to Item and Customer. On the right, GLEntry is related to Account and CostCenter. The Date table sits between them and is related to both fact tables, to SalesInvoiceLine on InvoiceDate and to GLEntry on PostingDate. Each relationship shows 1 at the dimension and an asterisk at the fact table, with arrows pointing toward the fact tables.
Figure 14.8 · Two Fact Tables Sharing One Date Table (detail)

The ledger star: postings, accounts and cost centers

Detail of: A mock of Power BI's Model view with two stars. On the left, SalesInvoiceLine is related to Item and Customer. On the right, GLEntry is related to Account and CostCenter. The Date table sits between them and is related to both fact tables, to SalesInvoiceLine on InvoiceDate and to GLEntry on PostingDate. Each relationship shows 1 at the dimension and an asterisk at the fact table, with arrows pointing toward the fact tables.
Figure 14.8 · Two Fact Tables Sharing One Date Table (detail)

Leave out the closing entries, or net income is zero

Detail of: Two matrices of net income by fiscal year, 2024 to 2026. In the first, built on all postings, net income is zero in every year, because the closing entries reverse each year's revenue and expenses on December 31. In the second, built on a measure that excludes the closing entries, each year shows its net income, which equals the amount the year's closing entry transferred to retained earnings.
Figure 14.9 · The Income Statement With and Without the Closing Entries (detail)

Exclude the closes once, and reverse the sign

GL Amount =
CALCULATE (
    SUM ( GLEntry[Debit] ) - SUM ( GLEntry[Credit] ),
    GLEntry[IsYearEndClose] = FALSE ()
)

P&L Amount = - [GL Amount]
  • Revenue reads positive and expenses negative, so the total is net income
  • A balance sheet reverses by account type, never by NormalBalance

Check your understanding

What went wrong in each report?

  1. Net income is zero in every year
  2. Revenue appears as a negative number
  3. Accumulated depreciation is added to total assets
  4. Selecting a product changes the ledger’s totals

Each problem has its cause

  1. The closing entries were left in the measure
  2. Debits less credits was shown without reversing the sign
  3. Signs were set account by account from NormalBalance
  4. A relationship set to Both carries the filter across

Guided Tutorial 14.3: Modeling the Ledger and the Income Statement

Add the ledger and the income statement in nine steps

  1. Choose the ledger’s Tables
  2. Keep the columns the model needs
  3. Flag the closing entries
  4. Relate the ledger to its dimensions
  5. Write the ledger’s measures
  6. Build the income statement by year
  7. Write the expectation
  8. Chart the expense against its expectation
  9. Add the trial-balance test

Each year’s total is the year’s net income

Detail of: A mock of a Power BI matrix with the account types Revenue and Expense and their subtypes as rows, and fiscal years 2024, 2025, and 2026 as columns. Operating revenue shows positive amounts, and the expenses, the contra revenue, and the other charges negative ones, and each year's total row, outlined, is that year's net income. A card above the matrix, filtered to fiscal 2026, shows that year's net income, equal to the matrix's 2026 total.
Figure 14.10 · The Income Statement by Year (detail)

Expense spikes in the months with three pay dates

Detail of: A mock of a Power BI line chart of operating expense by month from January 2024 to December 2026, with a second, dashed line for the expected operating expense, the average of the three months before each month, or of fewer at the start of 2024. The actual line runs close to the expectation except in seven months, marked, where it is more than a fifth above it. They are February 2024, whose expectation is the start-up month alone, and the six months with three pay dates, the first of which, March 2024, has an expectation of only two months.
Figure 14.11 · Monthly Operating Expense Against the Average of the Three Months Before (detail)

Checkpoint

Before you build reports on the model, confirm the following:

  • The model has two fact tables, SalesInvoiceLine and GLEntry, sharing the Date table, and the closing entries are flagged.
  • The income statement’s total for each fiscal year equals that year’s net income, and a measure that keeps the closing entries shows zero.
  • The months whose operating expense deviates most from its expectation are February 2024 and the six months with three pay dates.
  • Test 3 returns equal debit and credit balances, equal to Chapter 6’s pre-closing trial balance.

14.13 Looking Ahead

The model answers the managers and the controller

  • A star with a date table that every visual shares
  • Measures for margin, discount rate and shares, read in their contexts
  • Comparisons with the prior year and with a month’s own history
  • The ledger, with the closes excluded and the signs handled once

Summary

  • Fact tables at a stated grain; dimensions that filter them directly
  • Relationships many to one and single; a second date inactive
  • Measures for totals and ratios; columns for values that belong to a row
  • CALCULATE replaces or removes filters; context transition links the two
  • Closes excluded, signs reversed, and every measure tested

Key terms

Calculated column · Context transition · Cross filter direction · DAX · DAX query view · Date table · Degenerate dimension · Dimension table · Fact table · Filter context · Grain · Inactive relationship · Iterator · Measure · Row context · Snowflake schema · Star schema · Time intelligence

Practice and next steps

  • Financial Accounting
    • Exercise 14.1: The Balance Sheet at Any Month-End
    • Exercise 14.2: Revenue by Invoice Date and by Ship Date
  • Managerial Accounting
    • Exercise 14.3: Monthly Comparisons with the Prior Year
    • Exercise 14.4: The Furniture Bridge as Measures
  • Auditing
    • Exercise 14.5: Testing the Model’s Relationships
    • Exercise 14.6: A Library of Control Totals

Next: Chapter 15: Reports for Management Decisions

About these slides

These slides accompany Accounting Analytics: An Integrated Approach, licensed under CC BY-SA 4.0. Every figure and table comes from the chapter:

https://aa.accountinganalyticshub.com/chapters/14-data-models-and-dax/chapter.html