Professional Documents
Culture Documents
Advanced DAX For Business Intelligence
Advanced DAX For Business Intelligence
DAX
for Business Intelligence
With Power BI Expert Aaron Parry
Quizzes and Assignments to test and reinforce key concepts throughout the
course, with detailed step-by-step solutions
1 This course is for users who already have basic DAX skills
• It is strongly recommended that you complete our Up & Running with Power BI Desktop course, or have a
solid understanding of measures, calculated columns, evaluation context, and common DAX functions
2 What you see on your screen may not always match mine
• Power BI features are updated frequently (often monthly), so tools and interface options may change over time
• I’m using Windows 10 on a PC/Windows machine (note that Power BI Desktop is currently unavailable for Mac)
www.Docs.Microsoft.com/en-us/dax DAX Guide (dax.guide) by sqlbi.com is DAX Studio is an open source tool
is the official Microsoft DAX reference a great resource to learn and explore that allows you to write, execute and
guide, and a great resource for DAX functions, category groups, analyze DAX queries, as well as
exploring DAX functions product compatibility, and more troubleshoot and optimize your code
1) In the “Preview Features” tab, 2) In the “Data Load” tab, deselect the 3) In the “Regional Settings” tab, make
deselect any active features while “Update Relationships”, “Autodetect new sure to use the “English (United States)”
you are taking this course relationships after data is loaded” and “Auto locale for import
date/time” options NOTE: You may need to update setting in both
the Current File and Global sections
This section reviews the core concepts you should already be familiar with,
including data modeling fundamentals (cardinality, filter flow, etc.) and
basic DAX (operators, evaluation context, common measures, etc.)
Data & Lookup Tables Primary & Foreign Keys Relationship Cardinality Filter Flow
This Calendar Lookup table provides additional attributes about each date (month, year, weekday, quarter, etc.)
This Product Lookup table provides additional attributes about each product (brand, name, retail price, etc.)
These columns are foreign keys; they These columns are primary keys; they uniquely identify each
contain multiple instances of each row of a table, and match the foreign keys in related data tables
value, and are used to match the
primary keys in related lookup tables
In this case, there is only ONE instance of each ProductKey in the Products
table (noted by the “1”), since each row contains attributes of a single product
(Name, SKU, Description, Retail Price, etc)
There are MANY instances of each ProductKey in the Sales_Data table (noted
by the asterisk *), since there are multiple sales associated with each product
PRO TIP:
Arrange your lookup tables above your data tables in your model as a visual reminder that filters flow “downstream”
*In some cases filters may default to “two-way” depending on your Power BI Desktop settings *Copyright 2018, Excel Maven & Maven Analytics, LLC
FILTER FLOW (CONT.)
In this case, the only valid way filter both Sales and Returns data by
Territory is to use the TerritoryKey field from the Territory_Lookup
table, which is upstream and related to both data tables
• Filtering using TerritoryKey from the Sales table yields incorrect
Returns values, since the filter context cannot flow upstream to
either one of the other tables
✓ Only include the data you need for analysis (no redundant
or unnecessary records or fields)
& Concatenates two values to produce one text string [City] & “ “ & [State]
&& Create an AND condition between two logical expressions ([State]=“MA”) && ([Quantity]>10)
|| (double pipe) Create an OR condition between two logical expressions ([State]=“MA”) || ([State]=“CT”)
IN Creates a logical OR condition based on a given list (using curly brackets) ‘Store Lookup’[State] IN { “MA”, “CT”, “NY” }
*Head to www.msdn.microsoft.com for more information about DAX syntax, operators, troubleshooting, etc.
*Copyright 2020, Excel Maven & Maven Analytics, LLC
COMMON DAX FUNCTION CATEGORIES
Common Examples: Common Examples: Common Examples: Common Examples: Common Examples:
• SUM • IF • CONCATENATE • CALCULATE • DATEDIFF
• AVERAGE • IFERROR • FORMAT • FILTER • YEARFRAC
• MAX/MIN • AND • LEFT/MID/RIGHT • ALL • YEAR/MONTH/DAY
• DIVIDE • OR • UPPER/LOWER • ALLEXCEPT • HOUR/MINUTE/SECOND
• COUNT/COUNTA • NOT • PROPER • RELATED • TODAY/NOW
• COUNTROWS • SWITCH • LEN • RELATEDTABLE • WEEKDAY/WEEKNUM
• DISTINCTCOUNT • TRUE • SEARCH/FIND • DISTINCT
• FALSE • REPLACE • VALUES Time Intelligence Functions:
Iterator Functions: • REPT • EARLIER/EARLIEST • DATESYTD
• SUBSTITUTE • HASONEVALUE •
• SUMX DATESQTD
• TRIM • HASONEFILTER •
• AVERAGEX DATESMTD
• UNICHAR • ISFILTERED •
• MAXX/MINX DATEADD
• USERELATIONSHIP •
• RANKX DATESINPERIOD
• COUNTX
*Note: This is NOT a comprehensive list (does not include trigonometry functions, parent/child functions, information functions, or other less common functions)
*Copyright 2020, Excel Maven & Maven Analytics, LLC
CALCULATE
Name of an existing measure, or a DAX List of simple Boolean (True/False) filter expressions
formula for a valid measure (Note: these require simple, fixed values; you cannot
Examples:
create filters based on other measures)
• [Total Orders] Examples:
• SUM(Returns[ReturnQuantity]) • Territory_Lookup[Country] = “USA”
• Calendar[Year] > 1998
PRO TIP:
CALCULATE works just like SUMIF or COUNTIF in Excel, except it can evaluate measures based on ANY
sort of calculation (not just a sum, count, etc.); it may help to think of it like “CALCULATEIF”
Bikes
Products[CategoryName] = “Accessories”
table, filtered down to only rows where
the product category is “Bikes”
= 342
1 1
Bikes
PRO TIP:
Calculated columns are typically used for filtering data, rather than creating numerical or aggregated values
• Unlike calculated columns, measure values aren’t visible within HEY THIS IS IMPORTANT!
As a rule of thumb, use measures
tables; they can only be “seen” within a visualization like a (vs. calculated columns) when a
chart or matrix (similar to a calculated field in an Excel pivot) single row can’t give you the
answer (in other words, when you
• Measures are evaluated based on filter context, which means need to aggregate)
they recalculate when the fields or filters around them change
(like when new row or column labels are pulled into a matrix or
when new filters are applied to a report)
PRO TIP:
Use measures to create numerical, calculated values that can be analyzed in the “values” field of a report visual
Filter & row context tells DAX exactly how to evaluate measures and calculated
columns in your data model (this is key for understanding advanced DAX topics)
• Filter context filters the tables in your data model • Row context iterates through the rows in a table
• DAX creates filter context when dimensions are • DAX creates row context when you add calculated
added to rows, columns, slicers & filters in a report columns to your data model
• CALCULATE can be used to systematically create or • Iterator functions (SUMX, RANKX, etc.) use row
modify existing filter context context to evaluate row-level calculations
• Filter context always travels (propagates) from the • Row context doesn't automatically propagate through
ONE side to the MANY side of a table relationship table relationships (need to use RELATED or
RELATEDTABLE functions)
THE You’ve just been hired as the lead Business Intelligence Analyst for Maven Roasters*, a
SITUATION small-batch coffee chain based in New York City
All you’ve been given is a collection of raw csv files containing sales and inventory records,
THE along with details about the company’s products, customers, stores and employees.
BRIEF Your goal is to use Power BI and DAX to answer key questions about the Maven Roasters
business, including sales trends, inventory, top products, budgets and more.
*This data is adapted from IBM #Cognos Analytics sample data and is for informational purposes only . These samples are provided “as is” without warranty of any kind. The example companies, organizations, products,
domain names, email addresses, people, places, and events depicted herein are fictitious, and no association with any real company, organization, product, person, place, or event is intended or should be inferred.
*Copyright 2020, Excel Maven & Maven Analytics, LLC
THE MAVEN ROASTERS DATA MODEL
DAX is powered by two internal engines (formula engine & storage engine)
which work together to compress & encode raw data and evaluate DAX queries
• Although these engines operate entirely behind the scenes, knowing how they work will help you
build advanced skills by understanding exactly how DAX thinks
Internal DAX There are two distinct engines that work together to process every DAX query:
Engines
the Formula Engine and the Storage Engine
Query Evaluation
FORMULA ENGINE STORAGE ENGINE
Data & Storage • Receives, interprets and executes all • Compresses and encodes raw data, and only
Types DAX requests communicates with the formula engine (doesn’t
understand the DAX language)
• Processes the DAX query then generates
Columnar a list of logical steps called a query plan • Receives a query plan from Formula Engine,
Structures executes it, and returns a datacache
• Works with the datacache sent back
from the storage engine to evaluate the • NOTE: There are two types of storage engines,
Compression & DAX query and return a result based on the type of connection you’re using:
Encoding
1. VertiPaq is used for data stored in-memory
(connected to Power BI via import mode)
VertiPaq
Relationships 2. DirectQuery is used for data read directly
from the source (i.e. Azure, PostgreSQL, SAP)
We’ll focus on the VertiPaq
storage engine in this course
Internal DAX
Engines
DAX QUERY: MEASURE OUTPUT:
Sales to Females:
Storage
Query Evaluation Engine
$912,184
Storage engine executes the
Data & Storage
plan and sends a datacache
Types back to the formula engine
VertiPaq
Relationships
Internal DAX
Engines
DAX QUERY: MEASURE OUTPUT:
Sales to Females:
Storage
Query Evaluation Engine
$912,184
Data & Storage Sure! Here’s the data you’ll
Types need to evaluate that query
DAX here! Aaron would like
me to evaluate this query
Columnar Great! Hey Aaron, the result
Structures for that measure is $912,184!
Got it. Hey storage
engine, can you grab
Compression & Formula some data for me? Formula
Encoding Engine Engine
VertiPaq
Relationships
Internal DAX
Engines
DAX uses 6 data types to store values:
DAX Data Type Power BI Data Type Storage Type Example
Internal DAX
Engines VertiPaq uses a columnar data structure, which stores data as individual columns
(rather than rows or full tables) to quickly and efficiently evaluate DAX queries
Query Evaluation
Columnar
Structures 1 2 3 4
Compression &
Encoding
VertiPaq
Relationships
Internal DAX
Engines The goal of compression and encoding is to reduce the amount of memory needed
to evaluate a DAX query.
Query Evaluation Based on a sample of data, one (or more) of the following methods will be used:
Internal DAX
Engines Value Encoding uses a mathematical process to determine relationships between
the values in a column, and convert them into smaller values for storage
Query Evaluation
• Value encoding only works for integer values (including currency), and cannot be applied to
strings or floating-point values
Internal DAX
Engines
Hash Encoding builds a “dictionary” of distinct items in a column, assigns a unique
integer value (index) to each item, and stores the data using the index values rather
than the full text strings
Query Evaluation
• With hash encoding, storage requirements are defined by the number of unique items in the
column (cardinality), NOT by the length of the string values themselves
Data & Storage
Types
Product Index Row Product Index
This is what Coffee Beans This is how the 0 1 Coffee Beans 0
Columnar you see data is stored
Structures
Tea 1 2 Tea 1
Bakery 2 3 Bakery 2
Bakery 2 4 Encoding dictionary
Compression &
Encoding Coffee Beans 0 5
Coffee Beans 0 6
VertiPaq Bakery 2 7
Relationships
Tea 1 8
Internal DAX
Engines Run Length Encoding (RLE) reduces the size of a column by replacing duplicate
rows with a table containing each distinct value and the count of instances
Query Evaluation • NOTE: RLE only works when the same value is repeated in consecutive rows, but the VertiPaq
engine automatically sorts data on import and refresh to find the optimal compression
VertiPaq 05672
4 instances
Relationships
05672
05672
Internal DAX
Engines
Columns can have both Run Length and either Hash (Dictionary) or Value encoding
• Compression type is determined by cardinality, number of repeat values, row count, and data type
Query Evaluation
City Zip City Index Row
City Index Zip City Index Count
59716 0 1
0 59716 0 2
Data & Storage 59716 0 2
Types 1 05672 1 5
05672 1 3
2 90210 2 4
05672 1 4
Columnar 3 83353 3 1
Structures 05672 1 5
Hash Encoding RLE Encoding
05672 1 6
Compression & 05672 1 7
Encoding
90210 2 8
This is how the “City Zip” data is
90210 2 9 encoded and stored by VertiPaq
VertiPaq
Relationships 90210 2 10
90210 2 11
83353 3 12
Internal DAX VertiPaq has a special way of mapping relationships between columns in your data
Engines
model, which allows it to evaluate complex, multi-column queries
• NOTE: This is NOT the same as creating table relationships in your data model; this is essentially
Query Evaluation a blueprint that VertiPaq uses to map pairs of primary & foreign keys across related tables
Internal DAX
Engines
STEP 3: Return a datacache
containing a filtered sales table
STEP 2: Use relationship to find and sends to formula engine
Query Evaluation all rows where product line = 1
DAX uses two engines: the Formula Engine & Storage Engine
• The Formula Engine interprets & evaluates DAX, and the Storage Engine compresses & encodes data
In this section we’ll cover some common techniques and best practices for working efficiently
with DAX, including shortcuts, comments, measure tables, and variables
Variables
Error Handling
PRO TIP:
If you use a square bracket “[“ when you call a measure, you’ll avoid having to filter
Variables through function names that also start with the same letter(s) as your measure name
Shortcuts Formatting is KEY for readability. Can you tell what this code does in 10 seconds?
Formatting
Evaluation Order
Comments
10
1
2
3
4
5
6
7
8
9
Ready?
Go!Up!
Time’s
Time’s Up!
Measure Tables
Error Handling
Variables
PRO TIP
Use shift + enter to split out and indent each component of your DAX formulas to make them more human
readable (TIP: try using daxformatter.com to quickly format your code)
Shortcuts Evaluation order is the process by which DAX evaluates the parameters in a function
• Individual functions typically evaluate from left-to-right, starting with the first
Formatting parameter (followed by the second, third, etc.)
• Nested functions evaluate from the inside-out, starting with the innermost function
Evaluation Order and working outward from there
Non-nested: Nested:
Comments
1 2 3
=IF(LogicalTest, ResultIfTrue, [ResultIfFalse]) =SUMX(
Measure Tables FILTER(
FILTER( ‘Table’,
RELATED( ‘Table’[Column]), 1
Error Handling
RELATED( ‘Table’[Column]), 2
‘Table’[Column]) 3
Variables
NOTE: The CALCULATE function evaluates using its own unique set of rules (more on this later!)
Shortcuts Non-Nested
Formatting
Evaluation Order
Nested
Comments
Measure Tables
Error Handling
Variables
Shortcuts Comments can help other users interpret your Comment Type Marker
code, and can be particularly helpful for complex Single Line Comment -- or //
Formatting
queries with multiple lines, nested functions, etc. Multi Line Comment /* … */
Evaluation Order
Comments
Measure Tables
Error Handling
PRO TIP
Variables Avoid putting comments at the end of your DAX query (below the last closing parenthesis), as they can be
missed or omitted by users and formatting tools
Shortcuts Creating a separate table to contain your DAX measures is a great way to stay
organized (you can even group your measures into folders within the table!)
Formatting
Comments
Add a placeholder value in the first row of the
table (can be anything you want)
Measure Tables
Name the table (i.e. “Measure Table”)
Error Handling
Load the table to your data model
Variables
Shortcuts
Error handling functions can be used to help identify missing data, and can be
particularly useful for quality assurance and testing
Formatting Returns a value if the first expression is an error and
IFERROR() the value of the expression itself otherwise
=IFERROR(Value,ValueIfError)
Evaluation Order ISBLANK() Checks to see if a value is blank, returns True or False =ISBLANK(Value)
Comments
Measure Tables
Error Handling
PRO TIP:
Variables
VertiPaq can’t optimize IFERROR and ISBLANK functions, so avoid using them in your
operational code (a better use is for temporary QA & testing)
Shortcuts Variables (VAR) are DAX expressions which can be reused multiple times within a query, and are
commonly used for two key purposes:
Formatting • Readability: Variables make complex code more human readable
• Performance: Variables are only evaluated once no matter how often they are used within a query
Evaluation Order
Shortcuts
DAX queries which use variables must include two key components: the declaration
expression and the return expression:
Formatting
Error Handling
Variables
The return expression (RETURN) is where
you evaluate the rest of your DAX query, and
reference any previously declared variables
Shortcuts
Variables are “locked in” as soon as the DAX engine reads them; this means you cannot
modify how a variable is defined later in your query (i.e. through a CALCULATE function)
Formatting
Comments
Measure Tables
Error Handling
Variables
Shortcuts Variables can be a helpful tool for testing or debugging your DAX code
Formatting
Variables
Scalar functions return a single value, rather than a column or table; common examples
include aggregation, conversion, rounding, and logical functions
Functions that can be used Functions that can be used Functions that can be used Functions that are used to Functions for returning
to dynamically aggregate to round values to different to analyze the data type or force a specific data type information about values in
values within a column levels of precision output of an expression conversion a conditional expression
Common Examples: Common Examples: Common Examples: Common Examples: Common Examples:
• SUM • FLOOR • ISBLANK • CURRENCY • IF
• AVERAGE • TRUNC • ISERROR • INT • AND
• MAX • ROUNDDOWN • ISLOGICAL • FORMAT • OR
• MIN • MROUND • ISNONTEXT • DATE • NOT
• COUNT • ROUND • ISNUMBER • TIME • TRUE/FALSE
• COUNTA • CEILING • ISTEXT • DATEVALUE • SWITCH
• DISTINCTCOUNT • ISO.CEILING • VALUE • COALESCE
• PRODUCT • ROUNDUP
• ITERATOR (“X”) • INT
FUNCTIONS • FIXED
PRO TIP:
For large datasets (1M+ rows) using COUNTROWS & VALUES
may put less strain on the DAX engines than DISTINCTCOUNT
*Copyright 2018, Excel Maven & Maven Analytics, LLC
PRO TIP: SUM VS. SUMX
There are several cases where DAX evaluates a basic query using a more complex
method behind the scenes. The simplified query is often called “syntax sugar”
Rounding ROUNDUP() Rounds a number up, away from zero =ROUNDUP(Number, NumberOfDigits)
Functions
Aggregation
Decimal Value: 3.12438 Time value: 9:34:14 AM
Functions
Information
Functions ROUND ( 3.12438, 2) = 3.12
ROUNDUP ( 3.12438, 2) = 3.13 FLOOR ( 9:34:14, “0:15”) = 9:30:00 AM
Conversion ROUNDDOWN ( 3.12438, 2) = 3.12 Rounds the minute component
Functions down to the nearest multiple
Useful to specify the precision
of a number, like customer age
Logical
Functions FIXED ( 3.12438, 2) = 3.12 CEILING ( 9:34:14, ”0:15”) = 9:45:00 AM
MAVEN
ROASTERS Jean LeBean (CEO)
3:15 PM KEY OBJECTIVES:
CHANNELS (12)
1. Add a new column in your
Hey there! Hoping you could do me a quick
favor - I’m having trouble figuring out the Customers table to calculate
actual ages of our customers, and I think it age
may be a rounding issue...
2. Use a rounding function to
make sure that ages are
Would you mind digging into our customer defined properly and
MESSAGES (23) records to see what you can figure out? formatted as whole
numbers
Jean LeBean 1
Information
DATE() Returns the specified date in datetime format =DATE(Year, Month, Day)
Functions
MAVEN
ROASTERS Mark Brewer (CFO)
12:39 PM KEY OBJECTIVES:
CHANNELS (12)
1. Create a new calculated
Jean and I were having a chat and could use
your help with a couple items: column to convert
Transaction_Date to yyyy-
mm-dd format
1. Can you add a column to the calendar table
to format the dates like “2020-08-30”? 2. Use a conversion function
to modify the [Cost]
MESSAGES (8) measure and ensure that
2. Could you please make sure that [Cost] values are always displayed
values are always formatted as currency in as currency (without simply
our reports? changing the format)
Mark Brewer 1
Aggregation
Functions
Checks if a given condition is met, and
IF() returns one value if the condition is TRUE, =IF(LogicalTest, ResultIfTrue, [ResultIfFalse])
and another if the condition is FALSE
Rounding
Functions
Aggregation SWITCH() Evaluates an expression against a list of values and returns one of multiple possible expressions
Functions
Logical
Functions
PRO TIP
SWITCH (TRUE) is a common Pattern to replace nested IF statements
Aggregation Returns the first argument that does not evaluate to BLANK. If all arguments
Functions COALESCE() evaluate to BLANK, BLANK is returned.
Rounding
Functions =COALESCE(Expression1, Expression2, […])
Information
Functions
Any value or expression that returns a scalar value
Examples:
Conversion
Functions • COALESCE(
SUM(‘Sales by Store’[quantity_sold]), PRO TIP:
0)
COALESCE replaces the IF + ISBLANK
Logical • COALESCE( pattern, makes your code more readable,
Functions [Yesterday Customer Revenue], and can be optimized by the engines
“-”)
MAVEN
ROASTERS Darren A. Xu (Manager)
1:32 PM KEY OBJECTIVES:
CHANNELS (12)
1. Create a calculated column
Hey there! I’m looking at my customer sales
and want to see it by quarter/year. I really using variables and
need a column in the calendar table that SWITCH(TRUE()) to create a
shows the quarter and the year together… single column containing both
quarter & year (i.e. Q1-2020,
Q2-2020, etc.)
Mind quickly setting that up ?
MESSAGES (13)
Darren Xu 1
CALCULATE is a powerful DAX function which is commonly used to modify filter context; in this
section, we’ll explore advanced topics like expanded tables, context transition, evaluation
order and modifiers
An expanded table consists of the base table (which is visible to the user), along with
columns from any related table connected via a 1-to-1 or many-to-1 relationship
Expanded Tables
Product Lookup Table Store Lookup Table
Product ID Name Category Store ID Address Manager
1 Brazilian - Organic Coffee beans 3 32-20 Broadway 6
Context
Transition 2 Old Time Diner Coffee beans 4 604 Union Street 11
3 Espresso Roast Coffee beans 5 100 Church Street 16
4 Primo Roast Coffee beans 6 122 E Broadway 21 Related fields from the Product
Evaluation Order 5 Columbian Medium Coffee beans 7 224 E 57th Street 26 and Store tables are accessible
1 1
to DAX as part of the
“expanded” Transactions table
Transactions Table
3
2
Expanded Tables
1
In this case, the expanded
Context version of the AW_Sales
Transition
table contains all fields from
the product, subcategory,
and category lookup tables
Evaluation Order
Modifiers
Context Transition is the process of turning row context into filter context
• By default, calculated columns understand row context but not filter context
Expanded Tables
• To create filter context at the row-level, you can use CALCULATE
Context
Transition
If we add a column to calculate the sum of
quantity_sold, we get repeating totals since
there is no filter context, and we can’t
Evaluation Order determine a unique value per row
1 Sum of Quantity =
2 CALCULATE(
3 SUM(
4 ‘Table’[quantity_sold])
5 )
Consider the following formula, defined as both a measure and a calculated column:
Context
Transition
Evaluation Order
[Customer Sales] is evaluated LAST, Both measures evaluate the same, since the
Evaluation Order using the modified filter context ALL modifier evaluates first and is overwritten
by the store_id and product_group filters
Modifiers are used to alter the way CALCULATE creates filter context, and are added
as filter arguments within a CALCULATE function
Expanded Tables
• Modifiers are typically used to change filter context, access inactive table relationships,
or change the way filters propagate (i.e. one-way to bidirectional)
Context
Transition
Expanded Tables
=REMOVEFILTERS ( TableNameorColumnName, [ColumnName], […] )
Context
Transition Table or column that you want to (Optional) Repeatable column names that allow you
clear the filters from to specifically remove filters from individual columns
within the base table
Examples:
Evaluation Order
• CALCULATE( Examples:
[Customer Sales], • CALCULATE(
REMOVEFILTERS( [Customer Sales],
‘Store Lookup’)) REMOVEFILTERS(
Modifiers
‘Store Lookup’[store_id]))
PRO TIP:
REMOVEFILTERS is an alias for ALL, but can only be used as a CALCULATE modifier (not as a table function)
Expanded Tables KEEPFILTERS() Does not remove an existing column or table filter for an individual CALCULATE expression
Context =KEEPFILTERS(Expression)
Transition
MAVEN
ROASTERS Karen Cupps (Manager)
8:32 AM KEY OBJECTIVES:
CHANNELS (12)
1. Create a matrix containing
Okay, so I’m trying to create a table to show
my store sales (Store 3) broken down by product group & store id on
product group and compared against the rows
other two stores (5 & 8). Could you help?
2. Use KEEPFILTERS to create
measures that show sales for
I’d also like to see store sales within each each of the 3 stores
MESSAGES (5) product group as a percentage of the total, to
3. Use REMOVEFILTERS with
see which stores are the biggest sales drivers
within the group. Thanks! variables to create a single
measure for % of Store Sales
Karen Cupps 1
Overall Total
Table and Filter functions return columns or tables rather than scalar values, and can be used
to either generate new data or serve as table inputs within DAX measures
Manipulating Tables Generating Data • Filtering out totals from measure results
• Reducing the number of rows returned from a table
• Generating new data from scratch
DAX functions with table arguments can typically accept either physical tables (i.e.
‘Sales by Store’) or calculated, virtual tables (with functions like FILTER, VALUES, etc.)
Calculated Tables
Manipulating
Tables
1 Total Sales =
2 SUMX(
1 Total Sales = FILTER(
2 SUMX( 3 ‘Sales by Store’,
Generating Data 4 ‘Sales by Store’[quantity_sold]) > 3
3 ‘Sales by Store’,
4 ‘Sales by Store’[quantity_sold]) 5 ),
6 ‘Sales by Store’[quantity_sold]) )
Manipulating
Tables
ALL() Returns all the rows in a table, or all the values in a column, ignoring any filters
Generating Data
=ALL(Table or ColumnName, [ColumnName1],…)
• ALL is both a table filter and a CALCULATE modifier
• Removes initial filter context
• Does not accept table expressions (only physical table references)
Calculated Tables =
STEP 3 DAX evaluates [Customer
Filtering Tables Sales] against the filtered
table (quantity sold > 3)
Manipulating
Tables
Returns a single column table of unique values when a column name is given.
DISTINCT() If a table is supplied, DISTINCT returns all unique combinations of values.
Calculated Tables
=DISTINCT(ColumnName or TableExpression)
Filtering Tables
The column you want to extract The table you want to extract unique
Manipulating
Tables unique values from combinations of values from
Examples: Examples:
• ‘Sales by Store’[CustomerID] • ‘Sales by Store’
Generating Data • ‘Sales by Store’[UnitPrice] • ‘Food Inventory’
PRO TIP:
Trying to build a relational model from a single, blended table? Use DISTINCT to create
new lookup/dimension tables by extracting unique values from fields in your data table!
Calculated Tables Returns a single column table of unique values when a column name is given. If a table
VALUES() name is supplied, VALUES returns the entire table (including duplicates) plus a blank row
Filtering Tables
=VALUES(TableName or ColumnName)
Manipulating
Tables
The table you want to pull all columns The column you want to extract
and all rows from (not unique) unique values from
Generating Data
Examples: Examples:
• ‘Sales by Store’ • ‘Sales by Store’[CustomerID]
• ‘Food Inventory’ • ‘Sales by Store’[UnitPrice]
MAVEN
KEY OBJECTIVES:
ROASTERS Jean LeBean (CEO)
3:08 PM 1. Check if the Ginger Scone
CHANNELS (12) product exists in the data
Hey – I’m looking at our product sales and I’m model
not seeing the new Ginger Scone that we
added for Fall. I know we’ve been selling them, 2. Use counting functions plus
but can’t find them in the report... DISTINCT & VALUES to create
a view that shows the blank
row
Would you mind digging into our product
MESSAGES (23) records to see what you can figure out? 3. Add a new visual to show the
Adam Songs 1 missing product id when the
blank product is selected
Jean LeBean 1
4. Update the data model to
include the new product
Hint: Product Lookup (Updated)
Calculated Tables
=SELECTEDVALUE(ColumnName, [AlternateResult])
Filtering Tables The column you want to return a single value from (Optional) The value returned when there is either no
Examples: value or more than one value in the specified column
(if omitted, blank is returned)
• ‘Customer Lookup’[customer_first_name]
Manipulating • ‘Product Lookup’[product] Examples:
Tables • “-”
• “NA”
Generating Data
Removes all report context filters in the table except the filters
ALLEXCEPT() applied to the specified columns in the query
Calculated Tables
=ALLEXCEPT(TableName, [ColumnName],[ColumnName], […])
Filtering Tables Name of an existing table (the use of table Additional column references within the same
expressions is not allowed here) referenced table or a table that is on the one-side of the
relationship (adding additional columns is optional)
Examples:
Manipulating
‘Sales by Store’ Examples:
Tables
• ‘Sales by Store’[product_group]
‘Returns’ • ‘Sales by Store’[product_category]
•
•
‘Calendar’[Transaction_Date]
•
FILTER(
Generating Data ‘Sales by Store’,
‘Sales by Store’[store_id] IN {2,5,7,9,10})
PRO TIP:
ALLEXCEPT is typically used as a CALCULATE modifier and not a stand-alone table function
Manipulating
Tables
Generating Data
The measure above returns
Customer Sales by store ID
and Date, but ignores filter
context created by other
fields (i.e. Product Category)
KEY OBJECTIVES:
MAVEN
ROASTERS Adam Songs (Head Barista)
10:13 AM
1. Create a matrix with the store
CHANNELS (12)
id, product group and customer
Hey there! Can you please look at the sales name on rows, filtered based
for 2018 to our top 10 customers (excluding on Adam’s request
non-members) at store 8?
2. Use ALLEXCEPT to create a
I’m curious how much of our sales were measure that only accepts
driven by those customers, in total and as a % filters for the date, store ID
of all our sales during that period product group and customer
MESSAGES (1)
Adam Songs 1 3. Create a % of store-level sales
Would love to share this insight with Mark measure to calculate the
and Jean in our next roundtable! percent of sales by the top 10
customers at the store level
Hint: Try REMOVEFILTERS + KEEPFILTERS
Calculated Tables
=ALLSELECTED(TableNameOrColumnName, [ColumnName],[ColumnName], […])
Filtering Tables Name of a table or column that you want to Additional column references within the
remove filters from (NOTE: This input is required same referenced table (adding additional
unless being used as a CALCULATE modifier) columns is optional)
Manipulating
Examples: Examples:
Tables
• ALLSELECTED • ‘Sales by Store’[product_group]
• ‘Sales by Store’ • ‘Sales by Store’[product_category]
• ‘Sales by Store’[product_group]
Generating Data
Filtering Tables
Manipulating
Tables
Generating Data
Returns a table with selected columns from the table plus any new columns
SELECTCOLUMNS() specified by the DAX expressions
Calculated Tables
=SELECTCOLUMNS(Table, Name, Expression, […] )
Filtering Tables
Any DAX expression that returns a Name of the new column to be Any expression that returns a scalar
table added, must be wrapped with value (i.e. column reference, integer or
double quotes. Repeatable string). Repeatable
Manipulating Examples:
Tables Examples: Examples:
• ‘Sales by Store’
• ‘Food Inventory’ • “Employee Name & ID” • ‘Employees’[ID]
• FILTER( • “Employee Full Name” • [First Name] & “ “ & [Last Name]
Generating Data ‘Employees’,
‘Employees’[ID] IN {2,5,7,9,10})
PRO TIP:
SELECTCOLUMNS is an iterator function that’s useful when you
need to reduce the number of columns in a table for calculation
Returns a table with selected columns from the table plus any new columns
ADDCOLUMNS() specified by the DAX expressions
Calculated Tables
=ADDCOLUMNS(Table, Name, Expression, […] )
Filtering Tables
Any DAX expression that returns a Name of the new column to be Any expression that returns a scalar
table added, must be wrapped with value (i.e. column reference, integer or
double quotes. Repeatable string). Repeatable
Manipulating Examples:
Tables Examples: Examples:
• ‘Sales by Store’
• ‘Food Inventory’ • “Employee Name & ID” • ‘Employees’[ID]
• FILTER( • “Employee Full Name” • [First Name] & “ “ & [Last Name]
Generating Data ‘Employees’,
‘Employees’[ID] IN {2,5,7,9,10})
SUMMARIZE() Creates a summary of the input table grouped by the specified columns
Calculated Tables
=SUMMARIZE(Table, GroupBy_ColumnName, [Name], [Expression])
Depreciated and
Filtering Tables not recommended
Any DAX expression that returns a table of Name of an existing column to be used
data to create summary groups based on
Manipulating the values found in the column.
Tables Examples: Cannot be an expression
• ‘Sales by Store’
Examples:
• FILTER(
Generating Data ‘Sales by Store’, • ‘Sales by Store’[store_id]
‘Sales by Store’[product_id] = 16)
• ‘Customer Lookup’[customer_id]
MAVEN
ROASTERS Darren A. Xu (Manager) KEY OBJECTIVES:
9:37 AM
CHANNELS (12) 1. Use SUMMARIZE to create
Hey! I’ve noticed that pastries haven’t been a table that only shows the
selling well at store 5, and I’m wondering how
the unsold inventory impacts revenue. days with unsold pastries
2. Include columns to
Looking to share these results with Mark on calculate amount sold,
Tuesday. Would you be able to pull the amount unsold, and total
numbers and join that call?
MESSAGES (9) lost revenue
Darren Xu 1 3. Build a matrix to visualize
the results for Darren and
Lisa Latte
Mark
In this section, we’ll review four methods of manufacturing data from scratch:
Calculated Tables
Returns a single row table with new columns
ROW() =ROW(Name, Expression, […] ] )
specified by the DAX expression(s)
Filtering Tables
DATATABLE() Returns a table containing new, static data =DATATABLE(Name, Type, […] ], Data )
Generating Data
Uses curly brackets to return a table = { scalarExpr1, scalarExpr2, … }
Table Constructor { } containing one or more columns and records OR
= { ( scalarExpr1, scalarExpr2, … ),
( scalarExpr1, scalarExpr2, … ),
}
Filtering Tables
Name of the new column, enclosed in double Any DAX expression that returns a single scalar value
quotes. Repeatable.
Manipulating
Examples:
Tables Examples:
• [Customer Sales]
• “Profit” • SUM(
• “Cost” ‘Food Inventory’[quantity_start_of_day]
Generating Data
Filtering Tables
Column name (in quotes) Column data type Data points to add to table, called and
separated with curly brackets ({ })
Examples: Examples:
Manipulating
• “Test Number” • STRING Examples:
Tables
• “Value” • DOUBLE • {“First”, 1},
• INT • {“Second”, 2},
• CURRENCY • {“Third”, 3}
Generating Data
Filtering Tables
Start & End value for the series Value used to increment between Start &
Manipulating (can be positive or negative) End value (must be non-zero and
Tables positive)
Examples:
• 0, 1, 10.25, 50.234, etc. Examples:
• -1, -10.75, -45.5, etc. • .25, 1, 1.7745, 5, etc.
Generating Data
PRO TIP:
GENERATESERIES is a great way to build a custom range of data to be used as a parameter input
The table constructor { } can be used to build tables containing one or more columns
or rows, based on fixed values or DAX expressions which return scalar values
Calculated Tables • NOTE: Column headers can’t be defined using table constructor syntax
Filtering Tables 1 Single column with multiple rows: 3 Multi-row, multi-column table:
Manipulating
Tables
MAVEN
ROASTERS Jean LeBean (CEO) KEY OBJECTIVES:
3:15 PM
CHANNELS (12) 1. Use DATATABLE to
Mark and I are working on some forecasts, recreate the table that
and I need a new table showing target sales Jean needs for her
for April 2019, by product group.
forecasts
Below is a screen shot of what I’m looking for
-- thank you!
MESSAGES (23)
Jean LeBean 1
Mark Brewer 1
Calculated table joins are used to combine two or more tables of data; common examples
include CROSSJOIN, UNION, EXCEPT and INTERSECT
CROSSJOIN() Returns a table that contains the cartesian product of the specified tables
CROSSJOIN
=CROSSJOIN(Table, Table, […] ] ) Product Product Product Product Store
Category Group Category Group ID
Coffee Beverages Coffee Beverages 3
UNION Tea Beverages Tea Beverages 3
List of table expressions to include in the crossjoin
Bakery Food Bakery Food 3
Examples: Chocolate Food Chocolate Food 3
UNION() Combines or ”stacks” rows from two or more tables sharing the same column structure
EXCEPT() Returns all rows from the left table which do not appear in the right table
CROSSJOIN
EXCEPT
Example (churned customers):
=EXCEPT(‘Customers 2019’,‘Customers 2020’)
IMPORTANT NOTES:
✓ Both tables must contain the same number of columns
✓ Columns are compared based on positioning in their respective tables
✓ Column names are determined by the left table
✓ The resulting table does NOT retain relationships to other tables (can’t be used as an expanded table)
INTERSECT() Returns all the rows from the left table which also appear in the right table
CROSSJOIN
=INTERSECT(LeftTable, RightTable )
The left and right tables that will be used for joining
UNION
(NOTE: First table must be a table within the data model) LEFT RIGHT
Example (previous month active customers):
EXCEPT LeftTable: RightTable:
VALUES(‘Sales’[Customer ID]) CALCULATETABLE(
VALUES(’Sales’[Customer ID]), Resulting table contains rows
DATEADD(‘Calendar’[Date],-1, MONTH)) which appear in BOTH tables
INTERSECT
IMPORTANT NOTES:
✓ Order matters! (T1, T2) may have a different result set than (T2, T1)
✓ Columns are compared based on positioning in their respective tables
✓ Duplicate rows are retained
✓ Column names are determined by the left table
✓ The resulting table does NOT retain relationships to other tables (can’t be used as an expanded table)
MAVEN
ROASTERS Mark Brewer (CFO)
12:56 PM KEY OBJECTIVES:
CHANNELS (12)
1. Use CALCULATETABLE &
I’m looking at some of the revenue and profit
number and was hoping that you could tell me INTERSECT to look at
a little bit about our returning customers returning customers between
from 11/4/2018 – 11/17/2018 (weeks 45 & 11/4/2018 & 11/17/2018
46) and what their purchase behavior is like?
2. Add additional columns for
Revenue and Profit
MESSAGES (10)
I’d love to get an idea of revenue and profit for 3. Determine the total Revenue
Darren Xu these customers and Profit for repeat
Jamie Toast customers on week 46
Jean LeBean
Lisa Latte
Mark Brewer 1
Relationship functions allow you to access fields within DAX measures or calculated columns
through either physical or virtual relationships between tables
There are two key types of table relationships: PHYSICAL and VIRTUAL
Physical vs. Virtual • Physical relationships are manually created, and visible in your data model
Relationships
• Virtual relationships are temporary, and defined using DAX expressions
RELATED
RELATEDTABLE
These are physical relationships:
• Visible links between tables (typically 1:* cardinality)
USERELATIONSHIP
• Can be active or inactive
• Can be accessed using DAX functions like RELATED,
CROSSFILTER RELATEDTABLE or USERELATIONSHIP
• Best way to connect tables (but not always possible)
TREATAS
There are two key types of table relationships: PHYSICAL and VIRTUAL
Physical vs. Virtual • Physical relationships are manually created, and visible in your data model
Relationships
• Virtual relationships are temporary, and defined using DAX expressions
RELATED
RELATEDTABLE
This is a virtual relationship:
• Defined using DAX expressions
USERELATIONSHIP
• Used when a physical relationship doesn’t exist, or
cannot be created directly
CROSSFILTER • Often used to connect tables with different levels of
granularity (i.e. daily sales vs. monthly budgets/goals)
• Can be accessed using DAX functions like TREATAS
TREATAS
RELATED
=RELATED(ColumnName)
RELATEDTABLE
TREATAS
=RELATEDTABLE(Table)
RELATED
RELATEDTABLE Physical table you want to retrieve rows from (must reference
a table on the “many” side of a many-to-one relationship)
KEY OBJECTIVES:
MAVEN
ROASTERS Lisa Latte (Manager)
1:47 PM 1. Add a calculated column to the
Customer Lookup table and
CHANNELS (12)
create a variable for “Total Sales”
Hey there! Would it be possible to add a new
field to our customer records to label high 2. Add another variable called
value customers? “AllCustomers” to count total
customers
I’m thinking we could flag customers as “high 3. Add another variable that defines
value” if they have purchased more than the average sales
MESSAGES (13) average customer. Let me know! 4. Use RELATEDTABLE to create a
Darren Xu
variable that computes sales at
Jamie Toast the customer level
Jean LeBean
5. Return “High” if customer-level
Lisa Latte 1
sales are above the average.
Otherwise, return “Low”
RELATEDTABLE
Foreign (or primary) key of the Primary (or foreign) key of the HEY THIS IS IMPORTANT!
relationship relationship
USERELATIONSHIPS can only
USERELATIONSHIP Examples: Examples: be used in functions which
accept a filter parameter
• Food Inventory[Baked_Date] • Calendar[Transaction Date] (CALCULATE, TOTALYTD, etc.)
CROSSFILTER • Calendar[Transaction Date] • Food Inventory[Baked_Date]
TREATAS
PRO TIP:
If you have multiple date columns connected to a single calendar table, USERELATIONSHIP is a great way to
force measures to use inactive relationships without having to manually activate them in your model
Specifies cross filtering direction to be used for the duration of the DAX expression.
Physical vs. Virtual
Relationships
CROSSFILTER() The relationship is defined by naming the two columns that serve as endpoints
RELATEDTABLE
The two columns you want to use. Left
column is typically the “many” side and
right column is typically the “one” side Specifies the direction of the CROSSFILTER
TREATAS
PRO TIP
Instead of bi-directional relationships, use CROSSFILTER to enable two-way filtering ONLY in specific cases
MAVEN
ROASTERS Darren A. Xu (Manager) KEY OBJECTIVES:
9:19 AM
CHANNELS (12) 1. Create a measure called
How easy would it be to figure out the “Customers who Purchased” that
average order value for customers who make uses COUNTROWS & CROSSFILTER
purchases each month, broken down by to calculate the number of
different product groups? customers who made a purchase
in a given time period
Hint: Think about filter direction
I’d love to use that data to see if there are any
MESSAGES (28) interesting patterns or trends! 2. Create a measure that calculates
the average order value for
Darren Xu 1
“Customers who Purchased”
Jean LeBean
3. Create a matrix that that shows
Lisa Latte the previous two measures broken
down by Darren’s request
A table expression which generates the set of The list of output columns (cannot be an expression)
columns to be mapped. Table expression must be NOTE: The number of columns specified must match
RELATEDTABLE
based on physical table in data model. the number of columns in the table expression and
Examples: be in the same order
USERELATIONSHIP
• TREATAS( Examples:
VALUES(‘Calendar’[Year_ID)…
• ‘Target Sales’[Year]
• TREATAS(
CROSSFILTER • ‘Target Sales’[Year],
SUMMARIZE(‘Calendar’,
‘Calendar’[Year_ID], ‘Calendar[Month]… ‘Target Sales’[Month]
TREATAS
PRO TIP:
Use physical relationships (or USERELATIONSHIP functions) whenever possible, and only rely on
TREATAS if you are unable to create a direct relationship between tables
Both Sales by Store and Calendar are at the Date (daily) level
USERELATIONSHIP
Iterator functions allow you to loop through the same expression on every row of a table in
order to evaluate a single scalar value (i.e. max, min, average) or derive a new table
RANKX
SUMX() Returns the sum of an expression evaluated for each row in a table
Iterator Review
=SUMX(Table, Expression)
Iterator
Cardinality Aggregation to apply to
Table in which the expression will be Expression to be evaluated for
calculated rows
evaluated
each row of the given table
Examples:
CONCATENATEX Examples:
Examples:
• SUMX
• ‘Sales by Store’
• COUNTX • [Total Orders]
• FILTER( Sales,
AVERAGEX • AVERAGEX RELATED( • ‘Sales’[RetailPrice] * ‘Sales’[Quantity]
• RANKX ‘Products’[Category])=“Clothing”)
• MAXX/MINX
RANKX
PRO TIP:
Imagine the function adding a temporary new column to the table, calculating the value in
each row (based on the expression) and then applying the aggregation to that new column
Iterator cardinality is the number of rows in the table(s) being iterated; the more
Iterator Review
unique rows, the higher the cardinality (this is different from relationship cardinality)
Sales by Store
Iterator Index Date Price Product ID Quantity When iterators reference a single table, cardinality is simply
Cardinality the number of unique rows (in this case 912,424)
1 1/1/2017 $18 1 2
2 1/1/2017 $18 2 6 When using nested iterators, cardinality depends on
CONCATENATEX 3 1/1/2017 $14.75 3 1 whether you are using physical or virtual relationships:
… … … … … • For physical relationships, cardinality is defined as the
912,422 4/30/2019 $10 10 1 max number of unique rows in the largest table
912,423 4/30/2019 $3.75 79 2 • For virtual relationships, cardinality is defined as the
AVERAGEX
number of unique rows in each table multiplied together
912,424 4/30/2019 $3.75 36 1
RANKX
Physical relationship
Iterator Review
• Relationship between ‘Product Lookup’
and ‘Sales by Store’
Iterator
• ‘Product Lookup’ contains 88 rows
Cardinality • ‘Sales by Store’ contains 907,841 rows
Cardinality = 907,841
CONCATENATEX
Virtual relationship
AVERAGEX
• No physical relationship between
‘Product Lookup’ and ‘Sales by Store’
• ‘Product Lookup’ contains 88 rows
RANKX
• ‘Sales by Store’ contains 907,841 rows
Cardinality = 79,890,008
Iterator Review Evaluates an expression for each row of the table and returns the concatenation of
CONCATENATEX() those values in a single string, separated by a delimiter
Iterator
Cardinality =CONCATENATEX( Table, Expression, [Delimiter], [OrderBy_Expression], [Order])
CONCATENATEX
Table or table expression that Column that contains values to Optional arguments:
contains the rows you want concatenate or an expression that
• Delimiter: Used with concatenated expression
to return returns a value
• Examples: “,” “&” “-” “;” etc.
AVERAGEX
Examples: Examples: • OrderBy Expression: Expression used to sort the table
• Examples: Product Lookup[Product Category]
• ‘Product Lookup’ • ‘Product’[Category]
• CONCATENATEX( • ‘Employee’[Name] • Order: Order of results applied
RANKX • Examples: ASC, DESC
VALUES(‘Employee Lookup’)… • [Customer Sales]
• 7
Iterator Review
Iterator
Cardinality
AVERAGEX
MAVEN
ROASTERS Darren A. Xu (Manager)
2:50 PM KEY OBJECTIVES:
CHANNELS (12)
1. Create a visual for Store 5
Hey there! I’m hoping to look into Store 5
sales by employee, to see which employees that shows customer sales
account for largest percentage of total sales. by store and employee id
2. Create a measure to show %
of Total Sales for Store 5
Could you please create a visual that shows
Sales and % of Total Sales, with the ability to 3. Use CONCATENATEX to
MESSAGES (17) filter for any combination of Employee IDs? define a measure that shows
Darren Xu 1 the employee name(s)
selected and the % of Total
Sales for Store 5
Iterator Review AVERAGEX() Calculates the average (arithmetic mean) of a set of expressions evaluated over a table
=AVERAGEX(Table, Expression)
Iterator
Cardinality
Table, or table expression, that The expression that you want to evaluate
CONCATENATEX contains the rows to evaluate
Examples:
Examples:
• [Customer Sales]
• ‘Calendar’ • SUM[quantity_sold]
AVERAGEX
• ‘Product Lookup’
RANKX
HEY THIS IS IMPORTANT!
AVERAGE & AVERAGEX do NOT count days with zero sales when computing an average. To evaluate an
average over a date range that includes dates with no sales, use DIVIDE & COUNTROWS instead
Iterator Review
Here we’re using MAX, FILTER & ALL
to create a 30-day rolling time period
(based on the latest transaction date)
Iterator Once the rolling window is defined,
Cardinality
we can use AVERAGEX to calculate
the average sales over that period
CONCATENATEX • Note that we could also use
SUMX or COUNTX to calculate
the rolling total/count
AVERAGEX
PRO TIP:
Use a parameter to create a
RANKX dynamic, user-defined period!
MAVEN
ROASTERS Mark Brewer (CFO)
3:33 PM KEY OBJECTIVES:
CHANNELS (12)
1. Create a matrix to show total
Could you get me a visual showing our total and daily average profit by
and average profit, trended monthly from Jan month, for Jan 2018 – Apr 2019
2018 through Apr 2019?
2. Use GENERATESERIES &
SELECTEDVALUE to create a
Barry’s Beans closed their shop last month, parameter with increments of 7
and I’d like to track our profits to see the days over a 9-week period
MESSAGES (15)
impact. Could you please include a weekly
moving average that I can adjust as needed? 3. Create a measure using
Darren Xu AVERAGEX and the parameter
Jamie Toast you defined to calculate the
moving average profit
Mark Brewer 1
RANKX() Returns the ranking of a number in a list of numbers for each row in the table argument
Iterator Review
=RANKX(Table, Expression, [Value], [Order], [Ties])
SKIP: DENSE:
PRO TIP:
RANKX
If your “Total” row is showing a rank of 1, use IF &
HASONEVALUE with RANKX to exclude it from the rank!
MAVEN
ROASTERS Jamie Toast (Head Roaster)
9:13 AM KEY OBJECTIVES:
CHANNELS (12)
Hey there, I’m curious to see our profits for
1. Use variables and RANKX
the best-selling products in each category. to create a single measure
for Top 5 Products
Would you be able to show me a visual at the 2. Create a slicer for Product
product category level, only including profit Category to be able to
for the top 5 products within each category?
analyze the top 5 across
MESSAGES (23)
different categories
Darren Xu 1
Jamie Toast
Jean LeBean
DAX offers a range of powerful time intelligence functions, which allow you to build custom
calendars, define dynamic date ranges, and compare performance across specific periods
Automatic Date By default, Power BI automatically creates a hidden date table for any table that
Tables contains a Date or DateTime column on the one-side of a relationship
• Auto-generated calendars include all dates through the end of the year, regardless
Calendar
Functions of the actual date range in the table
Date Formatting
Time Intelligence
Functions
Week-Based
Calculations
Automatic Date
PROS: CONS:
Tables
Week-Based
Calculations
PRO TIP:
Turn OFF the auto date/time feature in Power BI Desktop and either import a date
dimension table or create your own using CALENDAR functions (more on this soon!)
Automatic Date
Tables
If you import or create your own date table, it must meet these requirements:
✓ Must contain all the days for all years represented in your fact tables
Calendar
Functions ✓ Must have at least one field set as a Date or DateTime datatype
✓ Cannot contain duplicate dates or datetime values
Date Formatting ✓ If using a time component within a date column, all times must be
identical (i.e. 12:00)
✓ Should be marked as a date table (not required but a best practice)
Time Intelligence
Functions
Automatic Date
Tables
CALENDAR() Returns a table with one column of all dates between start and end date
Examples:
Time Intelligence • CALENDAR(
Functions DATE( 2019,01,01), DATE(2020,12,31))
• CALENDAR(
DATE( YEAR ( MIN(Sales by Store[Transaction Date] )), 1, 1),
Week-Based
Calculations DATE( YEAR ( MAX(Sales by Store[Transaction Date] )), 12, 31)
Automatic Date Returns a table with one column of dates based on a fiscal year end month. The
Tables CALENDARAUTO() Range of dates is calculated automatically based on data in the model
Calendar =CALENDARAUTO(FiscalYearEndMonth)
Functions
An integer from 1 to 12 that represents the last month of the fiscal year.
Date Formatting Can be explicitly assigned or created using DAX functions (i.e. MIN/MAX)
Examples:
Time Intelligence • CALENDARAUTO(6)
Functions
• Calendar Table =
VAR MinYear = YEAR( MIN( ‘Sales by Store’[Transaction Date]))
Week-Based VAR MaxYear= YEAR( MAX( ‘Sales by Store’[Transaction Date]))
Calculations RETURN
FILTER( CALENDARAUTO(),
YEAR( [Date] ) >= MinYear &&
YEAR( [Date] ) <= MaxYear )
Automatic Date
Tables
Calendar
Functions
Time Intelligence
Functions
Week-Based
Calculations
Automatic Date
Use the FORMAT function to specify date/time formatting. Common examples include:
Tables
Date Formatting mmmm Show full month name July, August, etc.
Time Intelligence mm Display the month as a two-digit number 08, 09, 10, 11, etc.
Functions
q Display the quarter of the year 1, 2, 3, 4
Week-Based yyyy Show the year as a four-digit number 2018, 2019, 2020, etc.
Calculations
MAVEN
KEY OBJECTIVES:
ROASTERS Mark Brewer (CFO)
3:15 PM 1. Add columns to the calendar
CHANNELS (12) table to capture the weekday
Hey, I’m wondering what portion of our sales number and name
come in on weekends vs. weekdays. Could you
help with a quick analysis? 2. Add a binary Y/N column to
flag weekend dates
Jean and I would love to see a breakdown of 3. Use a Matrix visual to show
weekend vs. weekday sales, shown as a the percent of total sales for
MESSAGES (23) percent of total. Thanks! weekdays vs weekends
Jean LeBean
Lisa Latte
Mark Brewer 1
Automatic Date
Tables Time Intelligence functions allow you to define and compare custom time periods:
Calendar
Functions Performance-to-Date Time Period Shift Running Total
Functions commonly used to calculate Functions commonly used to compare Functions commonly used to calculate
Date Formatting performance through the current date performance between specific periods running totals or moving averages
Use these common time intelligence patterns for YTD, period-over-period, or running total calculations:
PRO TIP:
To calculate a moving average, use a running total calculation and divide by the number of intervals
Returns a column of dates from a parallel period, by shifting the dates specified
Automatic Date PARALLELPERIOD() forward or backward in time based on a given interval (month/quarter/year)
Tables
The name of a column containing dates Number of Intervals (positive or negative); Interval value can only be:
Date Formatting
or a one column table containing dates If a decimal is supplied, number is rounded • Month
to nearest whole integer • Quarter
Example: • Year
Time Intelligence Example:
• Calendar[Transaction_Date]
Functions
• 1, 2, 3, etc.
• -1,-2,-3 etc.
• -1.4 (-1) -1.5 (-2)
Week-Based
Calculations
HEY THIS IS IMPORTANT!
PARALLELPERIOD computes the entire period in the interval (i.e. entire year, quarter, etc.).
Values in total rows may not reflect the expected total if partial periods are present!
Automatic Date
Tables
Calendar
Functions
Time Intelligence
Functions
Week-Based
Calculations
Year-level total = Q4 2018 + Q1 2019
Returns a table containing a column of all dates from the previous quarter, based
Automatic Date PREVIOUSQUARTER on the first date in the date range specified
Tables
Calendar =PREVIOUSQUARTER(Dates)
Functions
Week-Based
Calculations HEY THIS IS IMPORTANT!
PREVIOUSQUARTER works similarly to With no date context, total is
PARALLELPERIOD (QUARTER) and computes the based on first visible date in
entire prior period (but handles totals differently) the table (5/9/2017)
Automatic Date
Tables
SAMEPERIODLASTYEAR() Returns a set of dates in the current selection from the previous year
Calendar = SAMEPERIODLASTYEAR(Dates)
Functions
Example:
Total Sales for 3/24/2017 –
Time Intelligence
• Calendar[Transaction_Date] 3/31/2017
Functions
Automatic Date
Tables
MAVEN
ROASTERS Jean LeBean (CEO)
3:15 PM KEY OBJECTIVES:
CHANNELS (12)
1. Using time intelligence
Hey there! I’m sure you’ve seen the increase
in our sales since Barry’s Beans went out of
functions to calculate total
business last month. Could you please share sales for the previous month,
the month-over-month change in sales from as well as the percent change
Mar-Apr 2019? month-over-month
2. Calculate the year-over-year
MESSAGES (23) One more thing – could you also look at April change in sales from April
2019 compared to April 2018? I’d love to see 2018 vs. April 2019
the YoY sales comparison too... Thanks!
Jean LeBean 1
Automatic Date
Tables
Week-based DAX calculations (i.e. previous week sales, same week last year)
can be especially challenging for several reasons:
Calendar • Can’t use standard DAX functions (i.e. PARALLELPERIOD, SAMEPERIODLASTYEAR)
Functions
• Weeks can start on various days (Sunday, Monday, etc.)
• There can be partial weeks in any given month, quarter or year (i.e. partial 53rd week)
Date Formatting
• Weeks can be grouped differently based on different fiscal calendars (i.e. 5-4-4, 4-5-4)
Time Intelligence
Functions
PRO TIP:
Week-Based Using a 5-4-4 or 4-5-4 fiscal calendar (common in the retail industry) can enable some
Calculations week-based calculations, but you still can’t use standard DAX time intelligence functions
Automatic Date
Tables 4 weeks
Time Intelligence
Functions
PROS: CONS:
Week-Based • Standardizes the number of • Does not have standard start & end
Calculations dates for years, quarters, or months
days in each week (7)
• Standardizes the number of • Cannot be used with standard DAX
weeks in each year (52) time intelligence functions
Automatic Date To calculate performance for the previous fiscal week, you can use DATEADD
Tables with an interval of -7 days:
Calendar
Functions
Time Intelligence
Functions
Week-Based
Calculations PRO TIP:
Use DATEADD with an interval of -364 days to compare the same week last year!
Automatic Date
Instead of a standard DAX performance-to-date functions (i.e. DATESYTD, DATESMTD),
Tables you can use a combination of CALCULATE, MAX, and HASONEVALUE:
Calendar
Functions Here we’re calculating QTD sales based on a 4-5-4 fiscal calendar
Date Formatting
Week-Based
Calculations
Automatic Date
Instead of a standard DAX time period shifting functions (i.e. PREVIOUSYEAR,
Tables PARALLELPERIOD), you can use CALCULATE, FILTER, ALL and SELECTEDVALUE:
Calendar Here we’re calculating QTD sales for the previous quarter based on a 4-5-4 fiscal calendar
Functions
Date Formatting
You can replace FiscalQuarter with
the fiscal month or fiscal week for
MTD and WTD calculations
Time Intelligence Just make sure to update the fiscal
Functions period to either 4, 12 or 52!
Week-Based
Calculations
MAVEN
ROASTERS Lisa Latte (Manager)
3:15 PM
CHANNELS (12) KEY OBJECTIVES:
Hey there! Looks like we’ve shifted into using
a standard 4-5-4 calendar. I’d love to be able 1. Using the 4-5-4 Calendar and
to look at our customer sales by YTD, QTD, [Customer Sales] create
and MTD measures for YTD and MTD
sales
Also, Darren and I were chatting, and we’d 2. Create a measure to compute
MESSAGES (23) love to look at week over week sales. Could week-over-week % change
you help us out here?
Darren Xu 3. Create a matrix (or two) to
Jamie Toast
Jean LeBean 1
visualize your results
Tools like DAX Studio and Power BI’s Performance Analyzer can you help you troubleshoot
issues, measure load times for visuals/DAX queries, and optimize your code
Power BI Desktop’s Performance Analyzer records user actions (like Excel’s macro
recorder), and tracks the load time (in milliseconds) for each step in the process:
Performance
Analyzer
DAX Query
• Shows the amount of time it takes for the
visual to send the query to the engines, and
Copy Query for the engines to return the result (Note:
DAX Studio can only help optimize this)
Visual Display
DAX Studio
• Shows the amount of time it takes for the
visual to populate, or “draw”, on the screen.
Includes time to retrieve web-based and
Optimization geocoded images
Workflow Other
• Shows the amount of time required by the
visual to prepare the query, wait for other
visuals to complete their queries and perform
other processing tasks
The Performance Analyzer includes a Copy Query option, which you can use to copy
the actual code that DAX generates behind the scenes to produce specific visuals:
Performance
Analyzer
Copy Query
DAX Studio
Optimization
Workflow
Remember that VALUES will include a blank if it exists in the
model? Well if you see a blank option in a slicer, this is why!
DAX Studio is a free tool that allows you to connect to your Power BI data model
to test and optimize your DAX queries
Performance
Analyzer
Copy Query
www.Daxstudio.org
DAX Studio
Optimization
Workflow
Performance
Analyzer 2 Analyze your query load times
• Each part of the query will likely take a different amount of time, and if the DAX Query load time is
long (100-200ms or more) you can likely optimize your code using DAX Studio
Copy Query
• Visual display load time may be decreased by changing the visual type or reducing data points
DAX Studio 3 Copy & paste or import queries into DAX Studio
• Copy and paste an individual query and analyze its performance in DAX Studio, or export the entire
performance analyzer results and use Analyze Performance Data to import a file containing all queries
Optimization
Workflow
4 Use DAX studio to optimize your code
• DAX Studio uses some specific functions which allow you to analyze your DAX queries (i.e. DEFINE,
EVALUATE and ORDER BY)
• In an optimized query, the storage engine (SE) should carry the majority of the CPU workload