Introduction To DAX
Introduction To DAX
Introduction To DAX
com
Who We Are
o BI Experts and Consultants
o Founders of www.sqlbi.com
• Problem Solving
• Complex Project Assistance
• Data Warehouse Assessments and Development
• Courses, Trainings and Workshops
o Book Writers
o Microsoft Gold Business Intelligence Partners
o SSAS Maestros – MVP – MCP
The DAX Language
o Language of
• Power Pivot
• Power BI
• SSAS Tabular
o DAX is simple, but it is not easy
o New programming concepts and patterns
Introduction to the DAX language
Introduction to DAX
What is DAX?
o Programming language
• Power Pivot
• SSAS Tabular
• Power BI
o Resembles Excel
• Because it was born with PowerPivot, in 2010
o Important differences
• No concept of «row» and «column»
• Different type system
o Many new functions
o Designed for data models and business calculations
Functional Language
DAX is a functional language, the execution flows with function calls, here is an example of
a DAX formula
=SUMX (
FILTER (
VALUES ( 'Date'[Year] ),
'Date'[Year] < 2005
),
IF (
'Date'[Year] >= 2000,
[Sales Amount] * 100,
[Sales Amount] * 90
)
)
If it is not formatted, it is not DAX.
Code formatting is of paramount importance in DAX.
=SUMX(FILTER(VALUES('Date'[Year]),'Date'[Year]<2005),IF('Date'[Year]>=2000,[S
ales Amount]*100,[Sales Amount]*90)
=SUMX (
FILTER (
VALUES ( 'Date'[Year] ),
'Date'[Year] < 2005
),
IF (
'Date'[Year] >= 2000,
[Sales Amount] * 100,
[Sales Amount] * 90
) www.daxformatter.com
Calculated Columns
o Columns computed using DAX
o Always computed for the current row
o Product[Price] means
• The value of the Price column (explicit)
• In the Product table (explicit, optional)
• For the current row (implicit)
• Different for each row
Measures
o Written using DAX
o Do not work row by row
o Instead, use tables and aggregators
o Do not have the «current row» concept
o Examples
• GrossMargin
• is a calculated column
• but can be a measure too
• GrossMargin %
• needs to be a measure
Naming Convention
o Measures do not belong to a table
• Avoid table name
• [Margin%] instead of Sales[Margin%]
• Easier to move to another table
• Easier to identify as a measure
o Thus
• Calculated columns Table[Column]
• Measures [Measure]
Measures vs Calculated Columns
o Use a column when
• Need to slice or filter on the value
o Use a measure
• Calculate percentages
• Calculate ratios
• Need complex aggregations
o Space and CPU usage
• Columns consume memory
• Measures consume CPU
Aggregation Functions
o Useful to aggregate values
• SUM
• AVERAGE
• MIN
• MAX
o Work only on numeric columns
o Aggregate only one column
• SUM ( Orders[Price] )
• SUM ( Orders[Price] * Orders[Quantity] )
The «X» Aggregation Functions
o Iterators: useful to aggregate formulas
• SUMX
• AVERAGEX
• MINX
• MAXX
o Iterate over the table and evaluate the expression for
each row
o Always receive two parameters
• Table to iterate
• Formula to evaluate for each row
Example of SUMX
For each row in the Sales table, evaluates the formula, then sum up all the results
Inside the formula, there is a «current row»
SUMX (
Sales,
Sales[Price] * Sales[Quantity]
)
Using Variables
Very useful to avoid repeating subexpressions in your code
VAR
TotalQuantity = SUM ( Sales[Quantity] )
RETURN
IF (
TotalQuantity > 1000,
TotalQuantity * 0.95,
TotalQuantity * 1.25
)
Date Functions
o Many useful functions
• DATE, DATEVALUE, DAY, EDATE,
• EOMONTH, HOUR, MINUTE,
• MONTH, NOW, SECOND, TIME,
• TIMEVALUE, TODAY, WEEKDAY,
• WEEKNUM, YEAR, YEARFRAC
Table Functions
Table Functions
o Basic functions that work on full tables
• FILTER
• ALL
• VALUES
• DISTINCT
• RELATEDTABLE
o Their result is often used in other functions
o They can be combined together to form complex
expressions
o We will discover many other table functions later in the
course
CALCULATED TABLES
o In the newest versions of Tabular (and in Power BI
Desktop), you can create calculated tables
o User interface is different in different products
Filtering a Table
SUMX (
FILTER (
Orders,
Orders[Price] > 1
),
Orders[Quantity] * Orders[Price]
)
The FILTER Function
o FILTER
• Adds a new condition
• Restricts the number of rows of a table
• Returns a table
• Can be iterated by an «X» function
o Needs a table as input
o The input can be another FILTER
Removing Filters
SUMX (
ALL ( Orders ),
Orders[Quantity] * Orders[Price]
)
The ALL Function
o ALL
• Returns all the rows of a table
• Ignores the filter context
• Returns a table
• That can be iterated by an «X» function
o Needs a table as input
o Can be used with a single column
• ALL ( Customers[CustomerName] )
• The result contains a table with one column
Mixing Filters
o Table functions can be mixed
o Each one requires a table
o Each one returns a table
o FILTER ( ALL ( Table ), Condition )
• Puts a filter over the entire table
• Ignores the current filter context
Mixing Filters
SUMX (
FILTER (
ALL( Orders ),
Orders[Channel]="Internet"
),
Orders[Quantity] * Orders[Price]
)
DISTINCT
Returns the distinct values of a column, only the ones visible in the current context
NumOfProducts :=
COUNTROWS (
DISTINCT ( Product[ProductCode] )
)
RELATEDTABLE
Returns a table with all the rows related with the current one.
NumOfProducts =
COUNTROWS (
RELATEDTABLE ( Product )
)
Example of RELATEDTABLE
Compute the number of red products for a category. Build a calculated column in the
Categories table:
NumOfRedProducts =
COUNTROWS (
FILTER (
RELATEDTABLE ( Product ),
Product[Color] = "Red"
)
)
Let us take a look at how DAX works
Evaluation Contexts
What is an Evaluation Context?
TotalSales := SUM ( Sales[SalesAmount] )
Rows
Slicers
Example of a Filter Context
Filter Context
o Defined by
• Row Selection
• Column Selection
• Report Filters
• Slicers Selection
o Rows outside of the filter context
• Are not considered for the computation
o Defined automatically by PivotTable, can be created
with specific functions too
Row Context
o Defined by
• Calculated column definition
• Defined automatically for each row
• Row Iteration functions
• SUMX, AVERAGEX …
• All «X» functions and iterators
• Defined by the user formulas
o Needed to evaluate column values, it is the concept of
“current row”
SUMX ( Orders, [Quantity]*[Price] )
SUM = 592
16x7=112
32x5=160
64x3=192
128x1=128
There Are Always Two Contexts
o Filter context
• Filters tables
• Might be empty
• All the tables are visible
• But this never happens in the real world
o Row context
• Iterates rows
• For the rows active in the filter context
• Might be empty
• There is no iteration running
o Both are «evaluation contexts»
Filtering a Table
SUMX (
FILTER (
Orders,
Orders[Price] > 1
),
Orders[Quantity] * Orders[Price]
)
Removing Filters
SUMX (
ALL ( Orders ),
Orders[Quantity] * Orders[Price]
)
The queen of all DAX functions
CALCULATE
CALCULATE Syntax
Filters are evaluated in the outer filter context, then combined together in AND and finally
used to build a new filter context into which DAX evaluates the expression
CALCULATE (
Expression,
Filter1,
… Repeated many times, as needed
Filtern
)
CALCULATE Examples
Compute the sum of sales where the price is more than $100.00
NumOfBigSales :=
CALCULATE (
SUM ( Sales[SalesAmount] ),
Sales[SalesAmount] > 100
)
CALCULATE (
SUM ( Sales[SalesAmount] ),
Sales[SalesAmount] > 100
)
Is equivalent to
CALCULATE (
SUM ( Sales[SalesAmount] ),
FILTER (
ALL ( Sales[SalesAmount] ),
Sales[SalesAmount] > 100
)
)
Clear filter on one column only
CALCULATE (
SUMX (
Orders,
ALL used with a
Orders[Amount] single column
), table
ALL ( Orders[Channel] )
)
CALCULATE Tasks
o Partially replaces the filter context
o Conditions
• Can replace a whole table
• Can replace a single column
SUMX (
Orders,
[Sales Amount]
)
SUMX (
Orders,
CALCULATE ( [Sales Amount] )
)
Time intelligence functions
Returns a table with a single column named “Date” containing a contiguous set of dates in
the given range, inclusive.
CALENDAR (
DATE ( 2005, 1, 1 ),
DATE ( 2015, 12, 31 )
)
CALENDAR (
MIN ( Sales[Order Date] ),
MAX ( Sales[Order Date] )
)
CALENDARAUTO 2015
Automatically creates a calendar table based on the database content. Optionally you can
specify the last month (useful for fiscal years)
--
-- The parameter is the last month
-- of the fiscal year
--
= CALENDARAUTO (
6
) Beware: CALENDARAUTO uses
all the dates in your model,
excluding only calculated
columns and tables
Set Sorting Options
o Month names do not sort alphabetically
• April is not the first month of the year
o Use Sort By Column
o Set all sorting options in the proper way
o Beware of sorting granularity
• 1:1 between names and sort keys
What is Time Intelligence?
o Many different topics in one name
• Year To Date
• Quarter To Date
• Running Total
• Same period previous year
• Working days computation
• Fiscal Year
o In short: anything related with time
• Handled in an intelligent way
Aggregations Over Time
o Many useful aggregations
• YTD: Year To Date
• QTD: Quarter To Date
• MTD: Month To Date
o They all need a Calendar Table
o And some understanding of CALCULATE
Year To Date (Time Intelligence)
DATESYTD makes filtering much easier
SalesAmountYTD :=
CALCULATE (
SUM ( Sales[SalesAmount] ),
DATESYTD ( 'Date'[Date] )
)
Handling Fiscal Year
The last, optional, parameter is the end of the fiscal year
Default: 12-31 (or 31/12 - locale dependent)
SalesAmountYTD :=
TOTALYTD (
SUM ( Sales[SalesAmount] ),
'Date'[Date],
"06-30"
)
SalesAmountYTD :=
CALCULATE (
SUM ( Sales[SalesAmount] ),
DATESYTD ( 'Date'[Date], "06-30" )
)
Same Period Last Year
Same period in previous year. CALCULATE is needed
Specialized version of DATEADD
Sales_SPLY :=
CALCULATE (
SUM ( Sales[SalesAmount] ),
SAMEPERIODLASTYEAR ( 'Date'[Date] )
)
Running Total
Running total requires an explicit filter
SalesAmountRT :=
CALCULATE (
SUM ( Sales[SalesAmount] ),
FILTER (
ALL ( 'Date' ),
'Date'[Date] <= MAX ( 'Date'[Date] )
)
)
Thank you!