0% found this document useful (0 votes)
11 views

DAX Functions

DAX (Data Analysis Expressions) is a programming language used in Microsoft SQL Server Analysis Services to compute business formulas over a data model consisting of linked tables. It allows for the creation of calculated columns and measures, with measures being calculated on demand based on user filters, while calculated columns are stored in the model and can increase file size. DAX also includes various functions and operators for data manipulation, including aggregation functions like SUM, AVERAGE, and logical functions like IF and SWITCH.
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views

DAX Functions

DAX (Data Analysis Expressions) is a programming language used in Microsoft SQL Server Analysis Services to compute business formulas over a data model consisting of linked tables. It allows for the creation of calculated columns and measures, with measures being calculated on demand based on user filters, while calculated columns are stored in the model and can increase file size. DAX also includes various functions and operators for data manipulation, including aggregation functions like SUM, AVERAGE, and logical functions like IF and SWITCH.
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 79

DAX

Data Analysis
Expressions

Granularity - accuracy of data categorization


DAX is the programming language of Microsoft sql server analysis services (SSAS)
DAX is a language specially designed to compute business formulas over a data model.

Understanding the data model:


A data model is a set of tables, linked by relationships.
we connect the ProductKey column of the Product table (which is also the primary key) to
the ProductKey column of the Sales table. This is the classical one-to-many relationship or a
relational model.
Using this relationship, any filter over columns of the Product table is reflected in a filter of
the Sales table. In other words, the relationship transfers the list of values filtered in the
ProductKey column of the Product table, to a correspondent filter applied to the ProductKey
column of the Sales table.
To create a model with dimensions and fact tables, it is recommended to use star schema
design principles. Power BI can be configured to enforce rules that filter dimension tables,
allowing Power BI model relationships to efficiently propagate those filters to fact tables.
.

DAX works only on tables. All the formulas must reference columns inside
tables.
Sales[SalesAmount] = Sales[ProductPrice] * Sales[ProductQuantity]
 DAX works on a data model containing many tables.
AllSales = SUM ( Sales[SalesAmount] ) //column level --- it is the grand total of the
SalesAmount column.
AllSales :=SUMX ( Sales, Sales[ProductQuantity] * Sales[ProductPrice])

Calculated Columns:
 Calculated columns are used when you want to perform row by row.
Ex: margin of sales, profit of the sales
 Calculated columns are added to table as a column.
 Calculated column values are stored in the powerbi.pbix file. Each calculated
column will increase the space that is used in that file and potentially increase
the refresh time.
 Calculated columns are very bad at aggregations because they don’t know about
how to filter.
 When we refresh new column values are re-calculated
 Name must be unique in table level.
Measures:
 Measures are calculated on demand. Power bi calculate the correct value when
the user requests it.
EX. When we drag the total sales measure onto the report, power bi calculate the
correct total and display it on visual.
 Measures do not add to the overall disk space of the power bi .pbix file.
 Measures are calculated based on the filters that are used by the report user.
These filters combine to create the filter context.
 Name must be unique across all tables.
 For measures we can add currency sign (measure tools->choose one in list of
currency types).
Measures are two types
1. Implicit measure (Basic aggregation, No formula, direct drag column from table)
2. Explicit measure (complex aggregation, with formula, drag measure from the table)

Operators:

All comparison operators except == treat BLANK as equal to number 0, empty string "",
DATE(1899, 12, 30), or FALSE. As a result, [Column] = 0 will be true when the value of
[Column] is either 0 or BLANK. In contrast, [Column] == 0 is true only when the value of
[Column] is 0.
Text concatenation operator -
& (ampersand) => Concatenation
Example => [First Name] & ',' & [Last Name]
Logical operators –
Use logical operators (&&) and (||) to combine expressions to produce a single
result.
The AND function in DAX accepts only two (2) arguments. If you need to perform an
AND operation on multiple expressions, you can create a series of calculations or, better,
use the AND operator (&&) to join all of them in a simple expression.

The logical operator || returns TRUE if any of the arguments are TRUE and returns
FALSE if all arguments are FALSE. With two arguments it works as the OR function. However,
the operator makes it easier to include multiple conditions in the same expression, because
the OR function only has two arguments and requires multiple calls for three or more
arguments.

Example => [Name] = "Roy" && [Salary] > 10000


Example => [Name] = "Roy" || [Salary] > 10000
The following formula shows the syntax of the AND function.
=IF (AND (10>9, -10<-1), “All true”, “One or more false”
Creates a logical OR condition between each row being compared to a table. Note: the table
constructor syntax uses curly braces.
'Product'[Color] IN { "Red", "Blue", "Black" }
Product[Color] = "Red" || Product[Color] = "Black"
Product[Color] IN { "Red", "Black" }
NOT(<logical>)
NOT('Global-Superstore'[Region] IN {"Africa", "Canada", "Caribbean"})

IF DAX Function (Logical)


Checks whether a condition is met, and returns one value if TRUE, and another value
if FALSE.

Price Group =IF( 'Product'[List Price] < 500, "Low")


Price Group =IF( 'Product'[List Price] < 500, "Low", "High")
Price Group =IF( 'Product'[List Price] < 500, "Low", IF('Product'[List Price] < 1500,
"Medium", "High"))
SWITCH – DAX Guide
SWITCH (
[A],
0, "Zero",
1, "One",
2, "Two",
"Other numbers"
)

SWITCH (
'Product'[Category],
"Audio", 0.15,
"Computers", 0.2,
"Cell phones", 0.13,
0
)
Writing TRUE() or TRUE produces the same result.
Stock Category = SWITCH(
True(),
Calendar[Month]="Jan", "January",
Calendar[Month] ="Feb", "February",
Calendar[Month] ="Mar", "March",
Calendar[Month] ="Apr", "April",
Calendar[Month] ="Jun", "June",
Calendar[Month] ="Jul", "July",
Calendar[Month] ="Aug", "August",
Calendar[Month] ="Sep", "September",
Calendar[Month] ="Oct", "October",
Calendar[Month] ="Nov", "November",
Calendar[Month] ="Dec", "December",
ISBLANK(Calendar[Month]),"null"
)
Stock Category = SWITCH(
Calendar[Month],
1, "January",
2, "February",
3, "March",
4, "April",
5, "May",
6, "June",
7, "July",
8, "August",
9, "September",
10, "October",
11, "November",
12, "December",
"null"
)

Variables in DAX
You can define a variable in any DAX expression by using VAR followed by RETURN. In one or several
VAR sections, you individually declare the variables needed to compute the expression; in the
RETURN part you provide the expression itself.

VAR SalesAmount = SUMX ( Sales, Sales[Quantity] * Sales[Net Price] )


VAR NumCustomer = DISTINCTCOUNT ( Sales[CustomerKey] )
RETURN
DIVIDE ( SalesAmount, NumCustomer )

Measure in Sales table


SalesPerCustomer :=
VAR SalesAmount =
SUMX (
Sales,
VAR Quantity = Sales[Quantity]
VAR Price = Sales[Net Price]
RETURN
Quantity * Price
)
VAR NumCustomer =
DISTINCTCOUNT ( Sales[CustomerKey] )
RETURN
DIVIDE (SalesAmount, NumCustomer)

Best Product Sales :=


VAR BestProducts = TOPN ( 10, Product, [Sales Amount] ) return multiple values
VAR SalesOfBestProducts =
SUMX (
BestProducts,
SUMX (
RELATEDTABLE ( Sales ),
Sales[Quantity] * Product[Unit Price]
)
)
RETURN
SalesOfBestProducts

Discounted Sales =
VAR AverageSales = AVERAGEX( Customer, [Sales Amount] )
VAR Result =
SUMX (
Customer,
VAR CustomerSales = [Sales Amount]
VAR Discount = 0.85
VAR Result =
IF (
CustomerSales >= AverageSales,
CustomerSales * Discount,
CustomerSales
)
RETURN
Result
)
RETURN
Result

Discounted Sales =
VAR AverageSales = AVERAGEX( Customer, [Sales Amount] )
VAR CustomerSales = [Sales Amount]
VAR Discount = 0.85
VAR Result =
SUMX (
Customer,
IF (
CustomerSales >= AverageSales,
CustomerSales * Discount,
CustomerSales
)
)
RETURN
Result

Discounted Sales =
SUMX (
Customer,
VAR AverageSales = AVERAGEX ( Customer, [Sales Amount] )
VAR CustomerSales = [Sales Amount]
VAR Discount = 0.85
VAR Result =
IF (
CustomerSales >= AverageSales,
CustomerSales * Discount,
CustomerSales
)
RETURN
Result
Aggregate DAX Function:
1. Sum(),Sumx():
SUM(<column>) //The column that contains the numbers to sum.
SUMX(<table>, <expression>)
Only the numbers in the column are counted. Blanks, logical values, and text are ignored.
2. MAX(), MIN()
MAX(<expression1>, <expression2>)
MAX(<column>)
MIN(<column>)
MIN(<expression1>, <expression2>)
 These functions support below datatypes. But these are not supporting boolean data
types
 Numbers
 Texts
 Dates
 Blanks // blank values are ignored
 Only When comparing two expressions, blank is treated as 0 when comparing. That is,
Max(1, Blank() ) returns 1, and Max( -1, Blank() ) returns 0.
 If both arguments are blank, MAX returns a blank. If either expression returns a value
which is not allowed, MAX returns an error.
 TRUE/FALSE values are not supported. If you want to evaluate a column of TRUE/FALSE
values, use the MAXA function.
max_m = MAX(blank column) -> returns blank value
3. MAXA(),MINA():
MAXA(<column>)
MINA(<column>)
 The MAXA function takes as argument a column, and looks for the largest value among
the following types of values:
 Numbers
 Dates
 Blanks // blank values are ignored
 Logical values, such as TRUE and FALSE. Rows that evaluate to TRUE count as 1; rows
that evaluate to FALSE count as 0 (zero).
 If you want to compare text values, use the MAX function.
Maxa(string column) -> returns 0 value.
4. MAXX() , MINX()
MAXX(<table>,<expression>,[<variant>])
MINX(<table>, < expression>,[<variant>])
 These functions support below datatypes:
 Numbers
 Texts
 Dates
 Blank values are skipped.
 TRUE/FALSE values are not supported.
 If the expression has variant or mixed value types such as text and number, then by
default MAXX considers only numbers. If <variant> = TRUE``, the maximum value is
returned.
max_m = maxX(orders,Orders[Category]*Orders[Sales]) //ERROR
max_m = maxX(orders,Orders[Category]*Orders[Sales],TRUE) //ERROR
max_m = maxX(orders,Orders[Category]*Orders[Sales],FALSE) //ERROR
max_m = maxX(orders,Orders[Category]) //OK
max_m = maxX(orders,blank column) //OK returns blank value
5. AVERAGE ,
AVERAGE(<column>)
 This function takes the specified column as an argument and finds the average of the
values in that column. If you want to find the average of an expression that evaluates to
a set of numbers, use the AVERAGEX function instead.
 Nonnumeric values in the column are handled as follows:
 If the column contains text, no aggregation can be performed, and the functions
returns blanks.
 If the column contains logical values or empty cells, those values are ignored.
 Cells with the value zero are included.
 When you average cells, you must keep in mind the difference between an empty cell
and a cell that contains the value 0 (zero). When a cell contains 0, it is added to the sum
of numbers and the row is counted among the number of rows used as the divisor.
However, when a cell contains a blank, the row is not counted.
 Whenever there are no rows to aggregate, the function returns a blank. However, if
there are rows, but none of them meet the specified criteria, the function returns 0.
Excel also returns a zero if no rows are found that meet the conditions.
max_m = AVERAGE(Orders[Sub-Category]) //ERROR
max_m = AVERAGE(Blank Column) //BLANK
6. AVERAGEA
AVERAGEA(<column>)
 The AVERAGEA function takes a column and averages the numbers in it, but also handles
non-numeric data types according to the following rules:
 Values that evaluate to TRUE count as 1.
 Values that evaluate to FALSE count as 0 (zero).
 Values that contain non-numeric text count as 0 (zero).
 Empty text ("") counts as 0 (zero).
 If you do not want to include logical values and text representations of numbers in a
reference as part of the calculation, use the AVERAGE function.
max_m = AVERAGEA(Orders[Sub-Category])//OK
max_m = AVERAGEX(Blank Column) //BLANK
 Whenever there are no rows to aggregate, the function returns a blank. However, if
there are rows, but none of them meet the specified criteria, the function returns 0.
Microsoft Excel also returns a zero if no rows are found that meet the conditions.
7. AVERAGEX
AVERAGEX(<table>,<expression>)
 The AVERAGEX function enables you to evaluate expressions for each row of a table, and
then take the resulting set of values and calculate its arithmetic mean. Therefore, the
function takes a table as its first argument, and an expression as the second argument.
 In all other respects, AVERAGEX follows the same rules as AVERAGE. You cannot include
non-numeric or null cells. Both the table and expression arguments are required.
 When there are no rows to aggregate, the function returns a blank. When there are
rows, but none of them meet the specified criteria, then the function returns 0.
8. COUNT , COUNTROWS
COUNT(<column>) Counts the number of rows in the specified column that contain non-
blank values.
COUNTROWS([<table>])The COUNTROWS function counts the number of rows in the
specified table, or in a table defined by an expression.
9

Item_Table

Sheet1
11

9. COUNTA
Counts the number of rows in the specified column that contain non-blank values.
Unlike COUNT, COUNTA supports Boolean data type.
10. COUNTX,COUNTAX
Counts the number of rows that contain a non-blank value or an expression that evaluates
to a non-blank value, when evaluating an expression over a table.
11. COUNTBLANK
Counts the number of blank cells in a column.
COUNTBLANK(<column>)
12. DISTINCTCOUNT, DISTINCTCOUNTNOBLANK
Counts the number of distinct values in a column.
DISTINCTCOUNT(<column>)
DISTINCTCOUNT function counts the BLANK value. To skip the BLANK value, use the
DISTINCTCOUNTNOBLANK function.
13. PRODUCT, PRODUCTX
Returns the product of the numbers in a column.
PRODUCT(<column>)
Only the numbers in the column are counted. Blanks, logical values, and text are ignored.

RELATED/RELATEDTABLE:
VLOOKUP IN Excel=RELATED function in DAX
RELATED FUNCTION RULES:

1. Only works when there is an active one to many relationships between 2 tables.
2. You can write the related function only in many sides of the table.
3. This function works on row context like column calculation and iterator functions.

TOY

Toy Id

1
*

This related function returns single value. Sales


RELATED(<column>)
New calculated Column 2 = RELATED(Toy[Price])
Measure1 = sumx(FILTER(Orders,Orders[Region]<>"Central"),Orders[Sales])
Measure2 = sumx(FILTER(Orders,RELATED(People[Region])<>"Central"),Orders[Sales])
Above two measures give same results.
RELATEDTABLE:
RELATEDTABLE(<tableName>) -> A table of values.
RELATEDTABLE Function can be write any where any relationship like one to many, many to
one, many to many.
Calculate column=RELATEDTABLE(Sales) //ERROR it returns table.
Calculate column=COUNTROWS(RELATEDTABLE(Sales) ) //OK
Table1 Table2 ON Table1
TEXT/STRING DAX Functions:
1. Len ()
Len (column name/ constant string) -> returns length of the string.
2. Combinevalues ()
It is similar like concatenate function.
COMBINEVALUES(<delimiter>, <expression>, <expression>[, <expression>]…)
Ex:
Combinevalues (“– “, “gopi”,” Krishna”,” T”); o/p gopi-Krishna-T
Calculated Column = COMBINEVALUES ("-”, Orders [Customer Name], Orders [Customer
Segment])
Using COMBINEVALUES Within Calculator Tables:

Combine Values Using DAX Inside A Measure:

3. Concatenate ()
It concatenates two column values only
Concatenate (col1, col2)
Ex: concatenate (“gopi”, “Krishna”); o/p: gopiKrishna
CONCATENATE(Customer[LastName], CONCATENATE(", ", Customer[FirstName]))
4. concatenateX ()
it is used in measure.
Using CONCATENATEX to combine multiple rows by specified column value.
Suppose you want below report data
Department Heads
HR Gopi Department Heads_measure
IT Krishna HR Gopi, Vijay
CADEM Mallik IT Krishna, Goutham
HR Vijay CADEM Mallik
PED Ramesh PED Ramesh
IT Goutham
Using concatenateX function, we get the Heads list of values based on department.
Create a measure
Heads_measure= CONCATENATEX(<table>, <expression/column name > [, <delimiter> [,
<orderBy_expression/column name> [, <order>]] ...])
ASC: To sort in an ascending order.
DESC: To sort in a descending order.
If omitted, default is ASC.

EX: CONCATENATEX (Products, [Product],", ", [Product Key], ASC)


returns Air Purifier, Detergent Powder, Floor Cleaner, Hand Wash, Soap.

= CONCATENATEX (Products, [Product],",", [Product Key], DESC)


returns Soap, Hand Wash, Floor Cleaner, Detergent Powder, Air Purifier.
CONCATENATEX(Employees, [FirstName] & " " & [LastName], ",")
5. Left ()
Get the number of characters from left side.
Left (column name/ string value, no of characters)
Ex: Left (“gopi Krishna”, 3); o/p gop
6. Right ()
Get the number of characters from right side.
Right (column name/string value, no of characters)
Ex: Right (“gopi krishna”,4) o/p: shna
7. Mid () - like substring function
Mid (column name/string value, starting position, no of characters)
Positions start at 1.
8. Lower ()
Lower (column name/string value)
9. Upper ()
Upper (column name/string value)
10. Trim ()
Trim white space characters from starting and ending and middle of the content.
Trim (column name/string value)
11. Substitute ()
substitute (column name/string value, “find value”, “replace value”)
Ex: Substitute ([employee Name],” sree”,” sir”);
12. Replace ()
Replace (column name/string value, starting index, no of characters, “replace string”)
The Start Position starts from 1 for the first character in the string.
Ex: Replace([phone],6,3,”***”)
REPLACE ( "DAX is so cool !", 11, 4, "fantastic")
Blank type
Blank is a DAX data type that represents and replaces SQL nulls. You can create a
blank by using the BLANK function, and test for blanks by using the ISBLANK logical function.
13. Blank ()
This function returns blank/empty value.
14. ISBLANK ()
ISBLANK (column name/string value) returns true when the column having blank
value otherwise false.
ISBLANK([Bonus])
If (ISBLANK([Bonus]), TRUE (), FLASE ())
15. Exact ()
Exact function compares two string column data. If both column data having same
data (it is case-sensitive), it returns true otherwise false.
Checks whether two text strings are exactly the same and returns TRUE or FALSE.
EXACT is case-sensitive.
EXACT (<text1>, <text2>)
Return Value
TRUE or FALSE.
16. Find () case sensitive
Find the location of the character or find the starting point of the given string in
Column.
Find (finding string, column name/string value, string position to start finding, not
found return value)
Find (“h”,” gopi krishna”,3,100); o/p: 10
Find (“Z”,” gopi krishna”,3,173); o/p: 173 (NOT FOUND RETURN VALUE)
17. Search () case- insensitive it is similar to find ()
Find the location of the character or find the starting point of the given string in
Column.
Search (finding string, column name/string value, string position to start finding, not
found return value)
Search (“H”,” gopi krishna”,3,100); o/p: 10
Search (“Z”,” gopi krishna”,3,173); o/p: 173 (NOT FOUND RETURN VALUE)
18. FIXED
Rounds a number to the specified number of decimals and returns the result as text.
You can specify that the result be returned with or without commas.
FIXED(<number>, <decimals>, <no_commas>)
no_commas (optional) A logical value: if 1, do not display commas in the returned
text; if 0 or omitted, display commas in the returned text.
Column 3 = FIXED(Orders[Sales],3,0) //1,287.450
Column 3 = FIXED(Orders[Sales],3,1) //1287.450
18. REPT
Repeats text a given number of times. Use REPT to fill a cell with a number of instances
of a text string.
REPT(<text>, <num_times>)
 If num_times is 0 (zero), REPT returns a blank.
 If num_times is not an integer, it is truncated.
REPT("85",3) //858585
REPT("85",-2) //ERROR
REPT("85",”2”) //8585
REPT("85",”A”) //ERROR
19. TRUE ()
TRUE () function always returns “True” value
20. FALSE ()
FALSE () function always returns “False” value.
21. IF () and OR ()
 DeptId=10, DeptId=20 then revised salary = salary + 1000 else salary
 RevSalary=IF (OR (Emp [DeptID]=10, Emp [DeptID]=20), Emp[salary]+1000,
Emp[salary])
 RevSalary=IF (Emp [DeptID]=10 || Emp [DeptID]=20, Emp[salary]+1000,
Emp[salary]))
22. IF () and AND ()
 DeptId=10 and Gender=M then revised salary = salary + 1000 else salary
 RevSalary=IF (AND (Emp [DeptID]=10, Emp [Gender]=”M”), Emp[salary]+1000,
Emp[salary])
 RevSalary=IF (Emp [DeptID]=10 && Emp [Gender]=”M”, Emp[salary]+1000,
Emp[salary]))
23. Switch () condition
Use switch () condition instead of multiple if conditions
MonthName= Switch (Emp [Month],1,” Jan”,2,” Feb”,3,” Mar”,4,” Apr”,5,” May”,6,”
Jun”,7,” Jul”,8,” Aug”,9,” Sep”,10,” Oct”,11,” Nov”,12,” Dec”);

RevNewSalary= SWITCH (TRUE (), EMP[Salary]<2000,” low”, EMP [Salary]>=4000,”


High”, “Medium”)
24. IN { }
RevNewSalary = IF (Emp [DeptId] =10 || Emp [DeptId] =20 || Emp [DeptId] =30 ||
Emp [DeptId] =40, EMP [Salary]+10000, EMP [Salary]+20000)

RevNewSalary = IF (Emp [DeptId] IN {10,20,30,40}, EMP [Salary]+10000, EMP [Salary]


+20000)

25. IFERROR () returns 0 when error occurs else the value.

DailyWage=IFERROR (Emp [salary]/EMP [NoOfDays], 0)

= IFERROR (5/0,"Div by zero") returns Div by zero.


= IFERROR (5/1,"Div by zero") returns 5.
 If value or value_if_error is an empty cell, IFERROR treats it as an empty string value
("").
 the column or expression used for value and the value returned for value_if_error
must be the same data type.
26. FORMAT
Converts a value to text in the specified format.

Return value
A string containing value formatted as defined by format_string.

Note
 If value is BLANK, the function returns an empty string.
 If format_string is BLANK, the value is formatted with a "General Number" or
"General Date" format (according to value data type).

predefined numeric formats


= FORMAT( 12345.67, "General Number")
= FORMAT( 12345.67, "Currency")
= FORMAT( 12345.67, "Fixed")
= FORMAT( 12345.67, "Standard")
= FORMAT( 12345.67, "Percent")
= FORMAT( 12345.67, "Scientific")
Returns:
1. 12345.67 "General Number" displays the number with no formatting.
2. $12,345.67 "Currency" displays the number with your currency locale formatting. The
sample here shows the default United States currency formatting.
3. 12345.67 "Fixed" displays at least one digit to the left of the decimal separator and two
digits to the right of the decimal separator.
4. 12,345.67 "Standard" displays at least one digit to the left of the decimal separator and
two digits to the right of the decimal separator and includes thousand separators. The
sample here shows the default United States number formatting.
5. 1,234,567.00 % "Percent" displays the number as a percentage (multiplied by 100) with
formatting and the percent sign at the right of the number separated by a single space.
6. 1.23E+04 "Scientific" displays the number in scientific notation with two decimal digits.
Comparison operators:
NOTE: By default, string comparison is case-insensitive for all operators.

“power Bi” = “POWER BI” TRUE

“power Bi” == “POWER BI” TRUE

Equal to (=) DAX Operator


The “equal to” operator = returns TRUE when the two arguments have the same value. This
operator does not perform any implicit conversion between strings, numbers, and Boolean values.

All comparison operators except == treat BLANK as equal to number 0, empty string "", DATE
(1899, 12, 30), or FALSE. As a result, [Column] = 0 will be true when the value of [Column] is either 0
or BLANK. In contrast, [Column] == 0 is true only when the value of [Column] is 0.

Strictly equal to (==) DAX Operator


The “strictly equal to” operator == returns TRUE when the two arguments have the same
value or are both BLANK.

NOT DAX Operator


NOT inverts the state of a boolean expression, transforming FALSE to TRUE, or TRUE to
FALSE.NOT is an operator and not a function. Because of the precedence rules, the expression that
follows NOT might be evaluated in an unexpected way if you think that NOT is a function.

-- NOT evaluates the result of the multiplication


(“NOT (FALSE) * FALSE", "" & NOT (FALSE) * FALSE),
-- NOT evaluates the result of the multiplication
(“NOT (FALSE * FALSE)", "" & NOT (FALSE * FALSE)),
-- NOT evaluates only the first FALSE function
(“(NOT FALSE) * FALSE", "" & (NOT FALSE) * FALSE)

Logical operators:
&& or AND ()

|| or OR ()

IN { }

Products [Color] IN {“Red", "Black”}


The following expressions are equivalent:

Product [Color] IN {“Red", "Blue", "Yellow”}

CONTAINSROW ({“Red", "Blue", "Yellow”}, Product [Color])

The following expressions using two columns are equivalent:

(‘Date'[Year], 'Date'[MonthNumber]) IN {(2018, 12), (2019, 1)}

CONTAINSROW ({(2018, 12), (2019, 1)}, 'Date'[Year], 'Date'[MonthNumber])


Date & Time Functions:
1. Year ():
Returns the year of a date as a four digit integer in the range 1900-9999.
Get the year value from Date column
Year ([Order Date]);
YEAR("03 MAR 2027") //2027
YEAR("MAR 2027") //2027
YEAR("MARCH 2027") //2027
YEAR("2027") //ERROR
YEAR("MAR2027") //ERROR
YEAR(TODAY())
2. Calendar (startdate, enddate) --
Table Name =calendar (Date (2010,1,1), Date (2020,12,31));
Table Name =calendar (Date (2010,1,1), TODAY());
3. Calendarauto ()
CALENDARAUTO([fiscal_year_end_month])
Table Name = Calendarauto (); I will give your calendar date based on available table data.
In this example, the MinDate and MaxDate in the data model are July 1, 2010 and June 30,
2011.
CALENDARAUTO() will return all dates between January 1, 2010, and December 31, 2011.
CALENDARAUTO(3) will return all dates between April 1, 2010, and March 31, 2012.
4. Date (year, month, day)
= DATE(2009,7,8) July 8, 2009:
DATE(0,1,2) //02-01-1900
year argument is between 0 (zero) and 99 (inclusive), that value is added to 1900 to
calculate the year. The following formula returns January 2, 1908: (1900+08).
DATE(08,1,2) //02-01-1908
DATE(99,1,2) //02-01-1999
DATE(100,1,2) //02-01-0100
If month is greater than 12, month adds that number of months to the next year month in
the year specified. The following formula returns the date February 2, 2009:
= DATE(2008,14,2)
The following formula returns the date February 4, 2008:
= DATE(2008,1,35)
5. Datediff (startdate, enddate, interval)
Interval represents return value type. Interval values like
SECOND,MINUTE,HOUR,DAY,WEEK,MONTH,QUARTER,YEAR
DATEDIFF ( StartDate, EndDate, YEAR )
DATEDIFF ( StartDate, EndDate, QUARTER )
DATEDIFF ( StartDate, EndDate, MONTH )
6. Datevalue (date column) ---it converts string date value to date value.
Converts a date in the form of text to a date in datetime format.
Column 3 = DATEVALUE("09/29/2023")
7. Day (date column)
= DAY("3-4-1007") //4
= DAY("March 4 2007") //4
8. Edate (date column, no of months)
How many months added to given date column.

9. EOMONTH

The following expression returns May 31, 2008, because the months argument is rounded to
2.
= EOMONTH("March 3, 2008",1.5)
= EOMONTH("March 3, 2008",1.4) //30-04-2008 months argument is rounded to 1.
10. ENDOFMONTH (date column) – Time intelligence functions
Returns the last date of the month in the current context for the specified column of dates.
(it is not returning last date of month; it returns maximum date of every month)
ENDOFMONTH(<date column>|<table having single date column>)
This function returns maximum date available in the specified month and year in the
column.
11. ENDOFQUARTER
Returns the last date of the quarter in the current context for the specified column of dates.
ENDOFQUARTER(<dates>)
12. ENDOFYEAR
Returns the last date of the year in the current context for the specified column of dates.
ENDOFYEAR(<dates> [,<year_end_date>])
ENDOFYEAR(Orders[Order Date]) -> returns end date of each year in specified column of
dates.
ENDOFYEAR(Orders[Order Date],”31/03”)
01 Apr 2014 to 31 March 2015 shows 31 March 2015
ENDOFYEAR(Orders[Order Date],”31/03/2006”) (any year value you can take)
01 Apr 2014 to 31 March 2015 shows 31 March 2015
ENDOFYEAR(Orders[Order Date],”27/08”)
28 Aug 2014 to 27 Aug 2015 shows 27 Aug 2015
13. STARTOFMONTH
Returns the first date of the month in the current context for the specified column of dates.
STARTOFMONTH(<dates>)
14. STARTOFQUARTER
Returns the first date of the quarter in the current context for the specified column of dates.
STARTOFQUARTER(<dates>)
15. STARTOFYEAR
Returns the first date of the year in the current context for the specified column of dates.
STARTOFYEAR(<dates>)
16. HOUR (time column)
Returns the hour as a number from 0 (12:00 A.M.) to 23 (11:00 P.M.).
The following example returns 15, meaning the hour corresponding to 3 PM in a 24-hour
clock. The text value is automatically parsed and converted to a date/time value.
= HOUR("March 3, 2008 3:00 PM")
17. Minute (time column)
Returns the minute as a number from 0 to 59, given a date and time value.
MINUTE(<datetime>)
The following example returns 45, which is the number of minutes in the time 1:45 PM.
= MINUTE("March 23, 2008 1:45 PM")
18. Second (time column)
Returns the seconds of a time value, as a number from 0 to 59.
SECOND(<time>)
The following formula returns 3, which is the number of seconds in the time represented by
the value, March 3, 2008 12:00:03.
= SECOND("March 3, 2008 12:00:03")
19. Month (date column)
Returns the month as a number from 1 (January) to 12 (December).
MONTH(<datetime>)
The following expression returns 3, which is the integer corresponding to March, the month
in the date argument.
= MONTH("March 3, 2008 3:45 PM")
20. Year (date column)
Returns the year of a date as a four-digit integer in the range 1900-9999.
YEAR(<date>)
The following example returns 2007.
= YEAR("March 2007")
= YEAR(TODAY())
21. Quarter (date column)
Returns the quarter as a number from 1 (January – March) to 4 (October – December).
QUARTER(<date>)
22. Weekday (date column, return type)
Returns a number from 0 to 7 identifying the day of the week of a date.
Return type =1 then week begins Sunday (1) to Saturday (7)
Return type=2 then week begins Monday (1) to Sunday (7)
Return type=3 then week begins Monday (0) to Sunday (6)
23. WEEKNUM(date column ,return type)
Returns the week number in the year.
WEEKNUM(<date>[, <return type>])
return type Week begins on System
1 or omitted Sunday 1
2 Monday 1
11 Monday 1
12 Tuesday 1
13 Wednesday 1
14 Thursday 1
15 Friday 1
16 Saturday 1
17 Sunday 1
21 Monday 2
Column 4 = WEEKNUM('Date Table'[Date Value],2)
24. Networkdays
Returns the number of whole workdays between two dates (inclusive)
NETWORKDAYS(<start_date>, <end_date> [, <weekend>, <holidays>])
This function returns no of days between two dates. And also exclude the weekends,
holidays also.
<weekend> parameter:
1 or omitted: Saturday, Sunday
2: Sunday, Monday
3: Monday, Tuesday
4: Tuesday, Wednesday
5: Wednesday, Thursday
6: Thursday, Friday
7: Friday, Saturday
11: Sunday only
12: Monday only
13: Tuesday only
14: Wednesday only
15: Thursday only
16: Friday only
17: Saturday only
<holidays> table: A column table of one or more dates that are to be excluded from the
working day calendar.
NETWORKDAYS (DATE (2022, 5, 28), DATE (2022, 6, 05), 1,
{
DATE (2022, 5, 30), DATE (2022,6,01)
}
)
NETWORKDAYS (start date, end date,1, holidays table column)
25. NOW () –Returns the current date and time in datetime format.
Current datetime= now ();
The following example returns the current date and time plus 3.5 days:
= NOW()+3.5 13-03-2025 15:55:38 +3.5
=17-03-2025 03:56:11
26. TODAY () - Returns the current date.
=TODAY() 13-03-2025 00:00:00
27. UTCNOW () – returns the current date and time (UTC time value) in datetime format.
NOW() -> 13-03-2025 16:03:08 UTC+5:30
UTCNOW() -> 13-03-2025 10:33:08
28. UTCTODAY()
TODAY() -> March, 13 2025 [00:03:56 (Thursday) at UTC +05:30].
UTCTODAY() -> March, 12 2025 [18:33:56 (Wednesday) at UTC 0].
29. TIME (hour, minute, second) – return time value along with default date.
Time (06,20,30); o/p: 30-12-1899 06:20:30 here 30-12-1899 is default date
TIME(hour, minute, second)
Return value
A time (datetime) ranging from 00:00:00 (12:00:00 AM) to 23:59:59 (11:59:59 PM).
30. TIMEVALUE ()
Converts a time in text format to a time in datetime format.
= TIMEVALUE(time text)
= TIMEVALUE("20:45:30")
31. YEARFRAC
Returns the year fraction representing the number of whole days between start_date and
end_date.
YEARFRAC(<start_date>, <end_date>, <basis>)
YEARFRAC(“Jan 1 2007”,”Mar 2 2007”) -> 0.16944444444444
Calculation:
In Jan 2007 days: 31
In Feb 2007 days: 28
In Mar 2007 days: 2
Total days: 61
Now result= 61/360 =0.16944444444444444
YEARFRAC(“Jan 1 2007”,”Mar 2 2007”,1) -> 0.164383561643836
YEARFRAC(“Jan 1 2007”,”Mar 2 2007”,2) -> 0.16666666666667
YEARFRAC(“Jan 1 2007”,”Mar 2 2007”,3) ->
YEARFRAC(“Jan 1 2007”,”Mar 2 2007”,1) ->

Math Functions:
1. INT ()
Rounds a number down to the nearest integer. Remove Decimals
salaryInt=INT([salary]);
= INT(1.5) //rounds the value to 1
2. ABS
Returns the absolute value of a number.
ABS(<number>) //A decimal number.
3. Currency ()
Converts into money with decimals.
Evaluates the argument and returns the result as currency data type.
Salesamt=Currency ([salesAmount])
The CURRENCY function rounds up the 5th significant decimal, in value, to return the 4th
decimal digit. Rounding up occurs if the 5th significant decimal is equal or larger than 5. For
example, if value is 3.6666666666666 then converting to currency returns $3.6667. However, if
value is 3.0123456789 then converting to currency returns $3.0123.
CURRENCY(Orders[sales]) //$75.25
CURRENCY(TrueFalse) will return $1.0000 for True values and $0.0000 for False values.
4. Round ()
Rounds a number to the specified number of digits.
ROUND(<number>, <num_digits>)
 If num_digits are greater than 0 (zero), then number is rounded to the specified number
of decimal places.
 If num_digits are 0, the number is rounded to the nearest integer.
 If num_digits are less than 0, the number is rounded to the left of the decimal point.
ROUND (2.15,1) o/p: 2.2
ROUND (21.5, -1) o/p: 20
ROUND(Orders[Sales],0) //ROUND THE VALUE
ROUND(Orders[Sales],-1)
Value value
Sales with -1 with -2
77.88 80 100
6.63 10 0
5.46 10 0
73.2 70 100
12.39 10 0
2.88 0 0
4.16 0 0

5. RoundUp ()
Its same like Round method

Round (102.3,0); 102


ROUNDUP (102.3,0); 103
ROUND (102.3,1); 102.3
ROUNDUP (102.3,1); 102.3
ROUND (78.8528,2); 78.85
ROUNDUP (78.8528,2); 78.86
6. ROUNDDOWN ()
Round (102.3,0); 102
ROUNDUP (102.3,0); 103
ROUNDDOWN (102.3,0); 102
Round (102.6,0); 103
ROUNDUP (102.6,0); 103
ROUNDDOWN (102.6,0); 102

Round (398.568,2); 398.57


ROUNDUP (398.568,2); 398.57
ROUNDDOWN (398.568,2); 398.56

Round (113.372,2); 113.37


ROUNDUP (113.372,2); 113.38
ROUNDDOWN (113.372,2); 113.37
7. DIVIDE ()
Performs division and returns alternate result or BLANK () on division by 0.
DIVIDE(<numerator>, <denominator> [, <alternate result>])

DIVIDE (5,2); 2.5


DIVIDE (5,0); BLANK
DIVIDE (5,0,1); 1
8. EVEN ()
EVEN (number) Returns number rounded up to the nearest even integer.
= EVEN (1.5) Rounds 1.5 to the nearest even integer 2
= EVEN (3) Rounds 3 to the nearest even integer 4
= EVEN (2) Rounds 2 to the nearest even integer 2
= EVEN (-1) Rounds -1 to the nearest even integer -2

9. ISEVEN ()
Returns TRUE if number is even, or FALSE if number is odd.
ISEVEN (number)
10. ODD ()
Returns number rounded up to the nearest odd integer.
ODD (number)
= ODD (1.5) Rounds 1.5 up to the nearest odd integer. 3
= ODD (3) Rounds 3 up to the nearest odd integer. 3
= ODD (2) Rounds 2 up to the nearest odd integer. 3
= ODD (-1) Rounds -1 up to the nearest odd integer. -1
= ODD (-2) Rounds -2 up (away from 0) to the nearest odd integer. -3
11. ISODD ()
Returns TRUE if number is odd, or FALSE if number is even.
ISODD (number)
12. POWER ()
Returns the result of a number raised to a power.
POWER(<number>, <power>)
= POWER (5,2); 25
13. Sqrt ()
Returns the square root of a number.
SQRT(<number>)
= SQRT (25); 5
If the number is negative, the SQRT function returns an error.
14. Fact ()
Returns the factorial of a number, equal to 1*2*3*…* Number.
Fact (1) 1
Fact (5) 120
Fact (9) 362,880
15. Sign ()
Return 1, when the number is positive
Return 0, when the number is 0
Return -1, when the number is negative.
ProfitSign= sign ([profit]);

Scalar Functions
Scalar function in a function that returns one single value. This value can be of any data type;
Date, Numeric, Text, etc. But it is always one single value.
Sales = Sum (FactInternetSales [SalesAmount])
We have many Scalar functions in DAX, here are a few examples:
 SUM/Average/Min/Max
 SUMX/MinX/MaxX/AverageX/CountX
 LastDate/FirstDate
 Calculate
 Related
Tabular Functions
Some functions return a table as the output, not a single value, a whole table. The table can
have multiple columns or just a single column depends on the function used. But it would be a table
structure with multiple values in it.
Copy of Customer Table = ALL(DimCustomer)

There are many tabular functions in DAX, here are a few;


 ALL, AllExcept
 RelatedTable
 SamePeriodLastYear
 DatesBetween/DatesInPeriod
 Summarize/GroupBy
 TreatAs

MAX/MAXX/MAXA
1- MAX DAX Function:
Returns the largest value in a column, or the larger value between two scalar expressions.

MAX (table[column])
 When used with a single column, the MAX function internally executes MAXX, without any
performance difference.
 Max_Measure = MAX (Orders [Sales])
 Equivalent to MAX function
MAXX (
table,
table[column]
)

When used with two arguments, the syntax:


MAX (exp1, exp2)

MAX function support Date, Number, Text data type.


MAX with Number data type column: -
Max_With_Number = MAX (Orders [Sales])

MAX with Date data type column: -


Max_With_Date = MAX (Orders [Order Date])

MAX with Text data type column: -


Max_With_Text = MAX (Orders [State or Province])
For Text Data type column, it will return MAX Alphabet Text.

logical value (Boolean value) Either of the two values true and false that indicate a truth value.

It does not support logical value. (ERROR)


Max_with_Boolean = MAX (SampleTable [Boolean])

You can compare two measures value using MAX function.


TotalProfit = Sum (Orders [Profit]) ---- 50000
TotalSales= Sum (Orders [Sales]) -------10000

Compare_Two_Expression = MAX ([TotalSales], [TotalProfit]) -------50000

The result is blank in case there are no rows in the table with a non-blank value.

2- MAXA DAX Function:


Returns the largest value in a column. Does not ignore logical values and text.
MAXA (table[column])
 For arguments that are not Boolean, the MAXA function internally executes MAXX,
without any performance difference.
MAXX (
table,
table[column])
When MAXA operates with a Boolean data type, it considers TRUE as 1 and FALSE as 0.

MAXA function support Date, Number & Boolean data type.

MAXA with Number data type column: -


MAXA_With_Number = MAXA (Orders [Sales])

MAXA with Date data type column: -


MAXA_With_Date = MAXA (Orders [Order Date])

MAXA_with_Boolean = MAXA (SampleTable [Boolean])


For Boolean/ Logical value, it will consider True=1, False=0

It does not support Text data type, it will return 0.


MAXA with Text data type column: -

MAXA_With_Text = MAXA (Orders [State or Province])

Output=0

MAXA (number column) -> returns maximum number value


MAXA (date column) ->returns maximum date value
MAXA (string column) -> returns 0
MAXA (Boolean column) -> it converts True as 1 and False as 0. we get max (1,0).
MAXA (BLANK column) -> it returns BLANK.

3- MAXX DAX Function:


Evaluates an expression for each row of a table and returns the largest value.

MAXX (table name, expression)

MAXX function support Date, Number & Text data type.


Maxx_With_Number = MAXX (Orders, Orders [Sales])

MAXX with Date data type column: -


Maxx_With_Date = MAXX (Orders, Orders [Order Date])

MAX with Text data type column: -


Maxx_With_Text = MAXX (Orders, Orders [State or Province])
For Text Data type column, it will return MAX Alphabet Text.
It does not support logical value.

Maxx_with_Boolean = MAXX (SampleTable, SampleTable [Boolean])


Here Boolean column data type is Bit
You can use Filter condition with MAXX Dax function
Suppose you want to get MAX sales only from “Furniture” category, so you can use Filter DAX with
MAXX.
MAXX_With_Filter = MAXX (FILTER (Orders, Orders [Product Category] ="Furniture"), Orders [Sales])

DAX – MIN, MINA & MINX Functions


1- MIN DAX Function:
Returns the smallest value in a column, or the smaller value between two scalar expressions.
Ignores logical values. Strings are compared according to alphabetical order.

When used with a single column, the MIN function internally executes MINX, without any
performance difference.

The following MIN call:

MIN (table[column])

corresponds to the following MINX call:

MINX (table, table[column])

When used with two arguments, the syntax:

MIN (exp1, exp2)

MIN function support Date, Number, Text data type.

MIN with Number data type column: -


MIN_With_Number = MIN (Orders [Sales])
MIN with Date data type column: -
MIN_With_Date = MIN (Orders [Order Date])

MIN with Text data type column: -


MIN_With_Text = MIN (Orders [State or Province])
For Text Data type column, it will return MIN Alphabet Text.

It does not support logical value.


MIN_with_Boolean = MIN (SampleTable [Boolean])
Here Boolean column data type is Bit, and it will give you error.

You can compare two measures value using MIN function.


TotalProfit = Sum (Orders [Profit]) ---- 50000
TotalSales= Sum (Orders [Sales]) -------10000
Compare_Two_Expression =MIN ([TotalSales], [TotalProfit]) -------10000
The result is blank in case there are no rows in the table with a non-blank value.

2- MINA DAX Function:

Returns the smallest value in a column.

MINA(<Column>)

When MINA operates with a Boolean data type, it considers TRUE as 1 and FALSE as 0.

MINA function support Date, Number & Boolean data type.

MINA with Number data type column: -


MINA_With_Number = MINA (Orders [Sales])

MINA with Date data type column: -


MINA_With_Date = MINA (Orders [Order Date])

MINA_with_Boolean = MINA (SampleTable [Boolean])


For Boolean/ Logical value, it will consider True=1, False=0

It does not support Text data type, it will return 0.


MINA with Text data type column: -

MINA_With_Text = MINA (Orders [State or Province])


Output=0

3- MINX DAX Function:

Evaluates an expression for each row of a table and returns the smallest value.

MINX (table name, expression)

MINX function support Date, Number & Text data type.


MINX with Number data type column: -
MINX_With_Number = MINX (Orders, Orders [Sales])

MINX with Date data type column: -


MINX_With_Date = MINX (Orders, Orders [Order Date])

MINX with Text data type column: -


MINX_With_Text = MINX (Orders, Orders [State or Province])
For Text Data type column, it will return MIN Alphabet Text.

It does not support logical value.


MINX_with_Boolean = MINX (SampleTable, SampleTable [Boolean])
Here Boolean column data type is Bit, it will give you error.

You can use Filter condition with MINX Dax function

DAX SUM and SUMX Functions


Suppose you want minimum sales value only for “Furniture” category, so you can use Filter DAX
with MINX.

1- SUM DAX function


MINX_With_Filter =MINX (FILTER (Orders, Orders [Product Category] ="Furniture"), Orders [Sales])

The SUM function is an aggregation function, and it calculates the sum of all numbers in a
column.
SUM(<Column>)

TotalSales = SUM('Global-Superstore'[Sales])

SUM function with Filter


Create a measure to get the sales of “Furniture” category.
SUM with Filter =CALCULATE (SUM('Global-Superstore'[Sales]), FILTER ('Global-Superstore', 'Global-
Superstore'[Category]="Furniture"))

SUM DAX with AND function


Get the “Furniture” category sales where “Sub category” is chairs.
SUM with AND = CALCULATE(SUM('Global-Superstore'[Sales]), FILTER ('Global-Superstore’, AND
('Global-Superstore'[Category] = "Furniture”, ‘Global-Superstore'[Sub-Category] ="Chairs")))

SUM DAX with OR function


SUM with OR = CALCULATE(SUM('Global-Superstore'[Sales]), FILTER ('Global-Superstore', OR ('Global-
Superstore'[Category] = "Furniture", 'Global-Superstore'[Sub-Category] ="Chairs")))

2- SUMX DAX function


SUMX is an iterator function. Returns the sum of an expression evaluated for each row in a
table. With this function you can operate on multiple columns in table row wise.

SUMX(<table>, <expression>)

Get Total sales to using SUMX function:


Total Sale = SUMX ('Global-Superstore', 'Global-Superstore'[Sales])

Suppose you want to see row wise sum of “Sales” & “Profit” columns together. Here, SUMX helps you
because it is iterator function and perform the operation row wise.
Sales + Profit =SUMX ('Global-Superstore’, 'Global-Superstore'[Sales] + 'Global-Superstore'[Profit])
Get sales of particular year
2013 Sales =SUMX (FILTER ( 'Global-Superstore', Year('Global-Superstore'[Order Date]) = 2013 ),
'Global-Superstore'[Sales])

SUMX with AND function


SUMX with AND = SUMX (FILTER ('Global-Superstore', AND ( 'Global-Superstore'[Category] =
"Furniture", 'Global-Superstore'[Sub-Category]="Chairs")), 'Global-Superstore'[Sales])

SUMX with OR function


SUMX with OR = SUMX (FILTER ('Global-Superstore', OR ('Global-Superstore'[Category] = "Furniture", 'Global-
Superstore'[Sub-Category] ="Chairs")), 'Global-Superstore'[Sales])

Below is the syntax of the AVERAGE function in Power BI DAX

= AVERAGE (Sales [Sales Amount])

The column is the numerical column we need to take the average of.

Since the AVERAGE function takes only numerical values for its evaluation, we need to be aware of
non-numerical values and their behaviour. Below are the points to be kept in mind with the non-
numerical values column.

 Any column which contains non-numerical values is ignored for aggregation, and the
DAX function returns the blank result.
 Logical results like “TRUE” and “FALSE” are ignored from the calculation in Power BI
 The empty cells are ignored from the calculation. The cells with 0 are considered for
calculation purposes.
 If the column contains logical values or empty cells, those values are ignored and the
rows are not counted.
 Cells with the value zero are included and the rows are counted for the divisor.
 Whenever there are no rows to aggregate, the function returns a blank. However, if
there are rows, but none of them meet the specified criteria, the function returns 0.
 This function takes the specified column as an argument and finds the average of the
values in that column.
 Does not support Logical value & Text Value
 Cells with the value zero are included.
 If Data type is Integer/ Numeric/ Decimal, Average skip the null value.

2- AVERAGEA DAX Function:

Returns the average (arithmetic mean) of the values in a column. Handles text and non-numeric
values.
Syntax:

AVERAGEA(<Column>)

Note :

The AVERAGEA function takes a column and averages the numbers, but also handles non-numeric
data types according to the following rules:

 It supports Logical values.


 Logical value TRUE count as 1 & FALSE count as 0 (zero).
 Values that contain non-numeric text count as 0 (zero).
 Empty text (“”) counts as 0 (zero).

The AVERAGEA function takes a column and averages the numbers in it and handles nonnumeric
data types according to the following rules −

 Values that evaluate to TRUE count as 1.


 Values that evaluate to FALSE count as 0 (zero).
 Values that contain non-numeric text count as 0 (zero).
 Empty text ("") counts as 0 (zero).

3- AVERAGEX DAX Function:

Calculates the average (arithmetic mean) of a set of expressions evaluated over a table.

Syntax:

AVERAGEX(<table>,<expression>)

Note:

The function takes a table as its first argument, and an expression as the second argument.

The AVERAGEX function enables you to evaluate expressions for each row of a table, and then take
the resulting set of values and calculate its arithmetic mean.

You cannot include non-numeric or null cells. Both the table and expression arguments are
required.

When there are no rows to aggregate, the function returns a blank. When there are rows, but none
of them meet the specified criteria, then the function returns 0.

Does not support Logical/ boolean values.


Remarks
The AVERAGEX function enables you to evaluate expressions for each row of a
table, and then take the resulting set of values and calculate its arithmetic mean.
Therefore, the function takes a table as its first argument and an expression as the
second argument.
In all other respects, AVERAGEX follows the same rules as AVERAGE. You cannot
include non-numeric or null cells.

Contains:
CONTAINS(<table>, <columnName>, <value>[, <columnName>, <value>]…)

= CONTAINS (InternetSales, [ProductKey], 214, [CustomerKey], 11185)


The following example creates a measure that tells you whether there were any Internet sales of
product 214 and to customer 11185 at the same time

CONTAINS (‘Product', 'Product'[Color], "Red”, ‘Product'[Brand], "Contoso" )

Similarly

FILTER ( 'Product', 'Product'[Color] = "Red" && 'Product'[Brand] = "Contoso" )

NOT CONTAINS (Customer, Customer [Continent], Store [Continent], Customer [State], Store [State],

Customer [City], Store [City])

CONTAINSROW function

 The IN operator internally executes CONTAINSROW.


Product [Color] IN {“Red", "Blue", "Yellow”}

CONTAINSROW ({“Red", "Blue", "Yellow”}, Product [Color])

 The number of scalarExprN must match the number of columns in table Expr.

(‘Date'[Year], 'Date'[MonthNumber]) IN {(2018, 12), (2019, 1)}

CONTAINSROW ({(2018, 12), (2019, 1)}, 'Date'[Year], 'Date'[MonthNumber])

(Customer [City], Customer [State])


IN {(“New York", "New York”), (“Columbus", "Ohio”)}

CONTAINSROW ({(“New York", "New York”), (“Columbus", "Ohio”)},

Customer [City], Customer [State])

 NOT IN is not an operator in DAX. To perform the logical negation of the IN operator, put
NOT in front of the entire expression.

For example, NOT [Color] IN {“Red", "Yellow", "Blue”}.

CONTAINSSTRING

A value of TRUE if the string WithinText contains the string FindText – the comparison is not case-
sensitive.

CONTAINSSTRING(<within_text>, <find_text>)

CONTAINSSTRING internally uses the SEARCH function.

Wildcard Characters

Symbol Description Example

* Represents zero or more characters bl* finds bl, black, blue, and blob

? Represents a single character h?t finds hot, hat, and hit

[] Represents any single character within the brackets h[oa]t finds hot and hat, but not hit

! Represents any character not in the brackets h[!oa]t finds hit, but not hot and hat

- Represents any single character within the specified range c[a-b]t finds cat and cbt

# Represents any single numeric character 2#5 finds 205, 215, 225, 235, 245, 255, 265,
275, 285, and 295

CONTAINSSTRINGEXACT ()

CONTAINSSTRINGEXACT internally uses the FIND function.

A value of TRUE if the string WithinText contains the string FindText – the comparison is case-
sensitive.

The CONTAINSSTRINGEXACT function does not accept wildcards to perform the search
TABLE LEVEL FUNCTIONS:
1. Selectcolumns

Returns a table with selected columns from the table and new columns specified by the DAX
expressions.

SELECTCOLUMNS (table, “column name”, expression)

Table_new=SELECTCOLUMNS (customer_tbla,” Country, State”, [Country] & “,” &[State])

Country, State

IND, JK
IND, MH
IND, WB
USA, CA
USA, WA
/* SELECTCOLUMNS is an iterator that returns a selection of columns / expressions evaluated in the
row context during the iteration over its first parameter. */

SELECTCOLUMNS (
TOPN (10, 'Product’),
"Product Category", 'Product'[Category],
"Product Subcategory", 'Product'[Subcategory],
"Product Color", 'Product'[Color],
"Product Name", 'Product'[Product Name],
"#Products", CALCULATE (COUNTROWS (‘Product’)),
"Sales", [Sales Amount]
)
2. ADDCOLUMNS
Returns a table with new columns specified by the DAX expressions.
ADDCOLUMNS(<table>, <name>, <expression> [, <name>, <expression>] …)
ADDCOLUMNS (ProductCategory,
“Internet Sales", SUMX(RELATEDTABLE(InternetSales_USD), InternetSales_USD[SalesAmount_USD])
, "Reseller Sales", SUMX(RELATEDTABLE(ResellerSales_USD), ResellerSales_USD[SalesAmount_USD])
)
/* ADDCOLUMNS is an iterator that returns its first argument after adding the column specified.
New columns are computed in the row context of ADDCOLUMNS, you need to invoke context
transition to generate a filter context, if needed. */

ADDCOLUMNS (
VALUES (‘Date'[Calendar Year]),
"@Year Number”, INT (RIGHT (‘Date'[Calendar Year], 4)),
"@Amount”, [Sales Amount], Please identify the
"@Quantity Wrong”, SUM (Sales [Quantity]), difference between two
"@Quantity Correct", CALCULATE (SUM (Sales [Quantity])) highlighted rows and
) check the output also.
3. CROSSJOIN
Returns a table that is a crossjoin of the specified tables.
CROSSJOIN(<table>, <table> [, <table>] …)

ADDCOLUMNS (
CROSSJOIN (VALUES ('Product'[Color]), VALUES ('Product'[Category])),
"#Prods", CALCULATE (COUNTROWS (‘Product’))
)

4. DATATABLE

Provides a mechanism for declaring an inline set of data values.

DATATABLE (ColumnName1, DataType1, ColumnName2, DataType2..., {{Value1, Value2...}, {ValueN, ValueN+1...}...})


orders1 = DATATABLE ("ID”, INTEGER, “Customer Name", STRING, "CITY”, STRING, "sales”, DOUBLE,
{{1,"GOPI","HYD",2345.904}, {2,"GOPI2","HYD",2345.904}, {3,"GOPI3","HYD",2345.904}})

It allows only inline set of values

orders2 = DATATABLE ("ID”, INTEGER, “Customer Name”, STRING,"CITY”, STRING, “sales”, DOUBLE,
{orders ['ROW ID']}) -----------ERROR

It not allows table column names

5. VALUES
When the input parameter is a column name, returns a one-column table that contains the
distinct values from the specified column. Duplicate values are removed and only unique
values are returned. A BLANK value can be added (considered as row).

When a table name is given, returns a table with the same columns and all the rows of the
table (including duplicates) with the additional blank row caused by an invalid relationship if
present.

VALUES (table column name / Table Name)

6. DISTINCT

Returns a one-column table that contains the distinct values from the specified column. In
other words, duplicate values are removed and only unique values are returned. (a blank value
also considers). A column of unique values.

Returns a table by removing duplicate rows from another table or expression. A table
containing only distinct rows.

DISTINCT (table column name / Table Name)

col_distinct = COUNTROWS(DISTINCT('Fact'[Fact]))
col_values = COUNTROWS(VALUES('Fact'[Fact]))
col_distinct_dim = COUNTROWS (DISTINCT (Dim [Dim]))
col_values_dim = COUNTROWS (VALUES (Dim [Dim]))
Dim Fact
A A
B B
A
B
C
D

D
C

Dim Fact
A A
B B
C A
B
C
D
D
C

Dim Fact
A A
B B
C A
B
C
C

Remember: in above 3 tables, blank cell in Dim table represents, other than primary key column
values.

 I have two tables (model), a dimension table (or master) and a facts table (or detail),
related one-to-many.
 I have created two table visuals, each one showing the fields of each model table.
 When I select a row in the table visual for dimensions, only the related rows in the table
visuals for facts are showed. That is the normal behaviour of Power Bi.
 But when I select a row (or rows) in the table visual for facts, the table visuals for
dimension is not filtered, showing only the related ones.
One – Many

You have multiple records for each value in the joining field between tables, for both tables. If you
think about it for a second, you can see that this scenario happens when you have tables that are
related to each other with no shared dimension in between! Let’s check one example; Let’s say I
have a Fact Inventory table and a Fact Sales table. They both have multiple records per product. and
I want to connect them together using the Product ID. this has to be a many-to-many relationship
because there is no product ID field which has unique values in it.

One to One

A one-to-one relationship means both columns contain unique values. This cardinality type isn't
common, and it likely represents a suboptimal model design because of the storage of redundant
data.

A one-to-one relationship happens only in one scenario when you have unique values in both tables
per column. An example of such scenario is when you have a Titles and a Titles Details table! They
both have one row per title.

When you have a one-to-one relationship between two tables, they are a good candidate to be
combined with each other using Merge in Power Query. Because both tables have the same number
of rows most of the time
VISUALISATION USING DIM VS FACT:

So, what is the difference between fact tables and dimensions?

Fact table

Fact table is a table, which typically:


 contains values we want to calculate
 is longer than dimension, because it repeats values that are unique in dimensions (like order
ID´s, product ID´s...).
Dimension

Dimension is a table, which adds some additional info to a fact table information.

For example, to ID product 11 it provides the info about price (91) and name (Cream).

Power BI
In reports generated from data models we normally use columns from both dimensions and fact
tables.

Now let’s define which columns are connected. These connections are called "relationships" and can
be simply done by dragging of column from one table to another. These columns are called "keys".
The key column must have unique values in dimension, but usually it has repeated values in a fact
table.

Reports

What does it mean for report creation (or Pivot tables in Power Pivot)?

 Usually, the columns from fact tables take place in fields like "Values" - they contain
numbers we want to calculate.
 Columns from dimensions usually belong to fields for grouping - like "Rows", "X Axis",
"Category"...

applying a filter on a column of a Dimension table should produce the same result as of applying the
same filter to a related column in the Fact table.
7. UNION

Creates a union (join) table from a pair of tables.

UNION(<table_expression1>, <table_expression2> [, <table expression>] …)

Return value:

A table that contains all the rows from each of the two table expressions. (allowing
duplicate rows also).

Important Points:

 The two tables must have the same number of columns.


 Columns are combined by position in their respective tables. (combine first
column of first table with second column of first column).
 The column names in the return table will match the column names in the first
Table.
 Duplicate rows are retained (FOUND).

UNION (UsaInventory, IndInventory)

8. INTERSECT
INTERSECT(<table_expression1>, <table_expression2>)

A table that contains all the rows in table_expression1 that are also in table_expression2.

Duplicate rows are retained. If a row appears in table_expression1 and table_expression2, it


and all duplicates in table_expression_1 are included in the result set.

Remarks

 Intersect is not commutative. In general, intersect (T1, T2) will have a different result set
than Intersect (T2, T1).
 Duplicate rows are retained. If a row appears in table_expression1 and
table_expression2, it and all duplicates in table_expression_1 are included in the result
set.
 The column names will match the column names in table_expression1.
 Columns are compared based on positioning, and data comparison with no type
coercion.

9. Except similar like minus


Returns the rows of the first table in the expression which do not appear in the second table.
EXCEPT(<table_expression1>, <table_expression2>)

Return value

A table that contains the rows of one table minus all the rows of another table.

Remarks

 If a row appears at all in both tables, it and its duplicates are not present in the result
set. If a row appears in only table_expression1, it and its duplicates will appear in the
result set.
 The column names will match the column names in table_expression1.
 The two tables must have the same number of columns.
 Columns are compared based on positioning, and data comparison with no type
coercion.
 The set of rows returned depends on the order of the two expressions.
10. FILTERS VS FILTER

DISTINCT COLUMN VALUES

Returns a table of the filter values applied directly to the specified column. (DISTINCT COLUMN
VALUES)

FILTERS (<column Name>)

FILTERS work same like values function in dax.

New_tbla= FILTERS (Column Name);


When the input parameter is a column name, returns a one-column table that
contains the distinct values from the specified column. Duplicate values are removed and
only unique values are returned. A BLANK value can be added (considered as row).
DIFFERENCE BETWEEN FILTERS VS VALUES function:

FILTERS VALUES
CALCULATETABLE ( CALCULATETABLE (
FILTERS (‘Product'[Category]), VALUES (‘Product'[Category]),
'Product'[Category] = "Audio" 'Product'[Category] = "Audio"
) )

CALCULATETABLE ( CALCULATETABLE (
FILTERS (‘Product'[Category]), VALUES (‘Product'[Category]),
'Product'[Category] IN {“Audio", "Computers”} 'Product'[Category] IN {“Audio", "Computers”}
) )

CALCULATETABLE ( CALCULATETABLE (
FILTERS (‘Product'[Category]), VALUES (‘Product'[Category]),
'Product'[Category] IN {“Audio", "abc”} 'Product'[Category] IN {“Audio", "abc”}
) )

CALCULATETABLE ( CALCULATETABLE (
FILTERS (‘Product'[Category]), VALUES (‘Product'[Category]),
'Product'[Category] IN {"abc”} 'Product'[Category] IN {"abc”}
) )
NO ROWS RETURN NO ROWS RETURN
CALCULATETABLE ( CALCULATETABLE (
FILTERS ( 'Product'[Category] ), VALUES ( 'Product'[Category] ),
'Product'[Color] = "Azure" 'Product'[Color] = "Azure"
) )
Color value filter having no effect on FILTERS Color value filter effect on VALUES data.
data.
-- Table filter include columns used in FILTERS -- Table filter include columns used in VALUES
CALCULATETABLE ( CALCULATETABLE (
FILTERS (‘Product'[Category]), VALUES (‘Product'[Category]),
FILTER (‘Product', 'Product'[Color] = "Azure”) FILTER (‘Product', 'Product'[Color] = "Azure”)
) )

ROW:

Row DAX function returns a table with a single row containing values that result from the
expressions given to each column.

ROW(<name>, <expression>, <name>, <expression>.....)

Table = ROW ("Total Sales", SUM (Orders [Sales]),"Total Profit", SUM (Orders [Profit]),"Total
Discount", SUM (Orders [Discount]))

RELATED VS RELATEDTABLE

RELATED function is used to get the parent table column name into child table.

Sub_category_c=RELATED(Product[‘sub_category’])

RELATEDTABLE function is used to

1. Create duplicate table.

New product table=RELATEDTABLE (product);

2. Get the aggregate value from child table to parent table.

Parent table is parent table, sales table is child table.

We add a new column in parent table, to get the sum of sales.

Total_sales=SUMX (RELATEDTABLE (sales), sum(sales[sales]));


JOINS:

Left Outer, Right Outer:


GENERATEALL, NaturalLeftOuterJoin, NaturalRightOuterJoin
GENERATEALL (table1, RELATEDTABLE (table2))
Full Outer:
Crossjoin, GENERATE, GENERATEALL
GENERATE (table1, table2)
GENERATEALL (table1, table2)
Inner Join
GENERATE, NaturalInnerJoin
GENERATE (table1, RELATEDTABLE (table2))
Left Anti, Right Anti:
Except
Table 1 Table 2

ID1 Support
Name
1 A
2 B
3 C
ID2
1 S1
2 S2
4 S4

GENERATE (table 1, Table 2) GENERATEALL (TABLE 1, TABLE 2)

ID1 Name ID2 Support


1 A 1 S1
2 B 1 S1
3 C 1 S1
1 A 2 S2
2 B 2 S2
3 C 2 S2
1 A 4 S4
2 B 4 S4
3 C 4 S4
ID1 Name ID2 Support
1 A 1 S1
1 A 2 S2
1 A 4 S4
2 B 1 S1
2 B 2 S2
2 B 4 S4
3 C 1 S1
3 C 2 S2
3 C 4 S4

GENERATE (TABLE 1, RELATEDTABLE (TABLE 2))


ID1 Name ID2 Support
1 A 1 S1
2 B 2 S2

GENERATEALL (TABLE 1, RELATEDTABLE (TABLE 2))


ID1 Name ID2 Support
1 A 1 S1
2 B 2 S2
3 C

GenerateSeries
Returns a table with one column, populated with sequential values from start to end.
GENERATESERIES(<startValue>, <endValue>[, <incrementValue>])
Return value
A single column table containing the values of an arithmetic series. The name of the
column is Value.
Remarks
 When endValue is less than startValue, an empty table is returned.
 incrementValue must be a positive value.
 The sequence stops at the last value that is less than or equal to endValue.

Table Constructor:
Returns a table of one or more columns.
{<scalarExpr1>, <scalarExpr2>, …} //returns a table of a single column.
{(<scalarExpr1>, <scalarExpr2>, …), (<scalarExpr1>, <scalarExpr2>, …), …} // returns a table of
one or more columns.
Summarizecolumns:
It is also like group by functionality like sql.
Summarizecolumns (column name1, column name2, column name3…, FILTER expression,
“new column name”, expression, “new column name”, expression...)
Return Value
A table which includes the combinations of values from the supplied columns, based on the
grouping specified.
Only rows for which at least one of the supplied expressions return a non-blank value are
included in the table returned.
If all expressions evaluate to BLANK/NULL for a row, that row is not included in the table
returned.
SUMMARIZE:
Returns a summary table for the requested totals over a set of groups.
SUMMARIZE (<table>, <groupBy_columnName>, [<groupBy_columnName>] …,
[<name>, <expression>] …)
Data Lineage is a key part of Data Governance within Power BI, showing you which data
sources are used by which datasets, and then by which reports.
It enables you to see the upstream and downstream path of your data.
CROSSFILTER:
Table A

Sales_id
Prod_id

Table C
Table B
Prod_id
Sales_id
Quantity
Sales_ref

We want Table B sales_ref wise Table C Quantity. In this Table B and Table C having not relations
ship directly. In this case we use CROSSFILTER mechanisum.

Way 1: you build “BOTH” (bi-directional) Relationship between Table B (filtering column
containing table) and Table A. (master table).

Way 2: using Dax CROSSFILTER function.

CROSSFILTER (many relationship filtering column table names, One relation table)

CROSSFILTER (Table B [Sale_id], Table A[Sale_id]) (relationship column Sale_id in


both table).

DimProduct DimSalesTerritory

FactInternetSales

CrossFilter (FactInternetSales [prod_id] , DimProduct[prod_id])

Remember:
1. In one to many relationships, for date columns participates in relationship, we lose hierarchy
in many side columns.
2. One-to-One, Many-to-Many relationships, which table column we drag into another table,
that column date hierarchy loose.
3. When date filed is related to another non-date field, loses date hierarchy in many sides.

Userelationship:

Orders table
DimDate table
Order_date
Date
Sales_date

Due_date

sales value ship date_m = CALCULATE (sum (Orders [Sales]), USERELATIONSHIP (Orders [Ship Date],
DimDate [Date]))

Userelationship (fact table column, dim table column);

CALCULATE VS CALCULATETABLE VS FILTER


DIFFERENCE BETWEEN FILTER AND CALCULATETABLE:
FILTER (tablename, filter)

Here filter accepting only given table column names only. If you want you can use
Parent (DIM) table column names with RELATED function. (filter works on row context)

CALCULATETABLE (tablename, filter)

Here filter accepting all table columns. (HERE no need of RELATED function while
accessing DIM Tables). (filter works on Filter Context )
FILTER VS CALCULATEDTABLE DIFF:

While the resulting tables are the same, the way the tables are created is completely different.
FILTER first saw the all products table, then ran the "is the product color red" test for each row of
this table, returning the rows that passed the test as a table. The products table has a total of 2517
rows, iterated each row in the same table 2517 times, returning 99 rows that passed the test.

CALCULATETABLE, on the other hand, first found the products with red color, while doing this, it did
not iterate through the rows, it worked directly on the values in the color column, then returned the
table with these products.

According to the examples above, the first difference between the two functions isFILTER being an
iterator. CALCULATETABLE is not an iterator.

The second difference is the "execution" order:

FILTER first reads the first parameter (table) and then returns rows from this table that match the
conditions.

On the other hand, CALCULATETABLE first applies the condition and then runs the first parameter
accordingly.

CALTBLA2 = CALCULATETABLE (ADDCOLUMNS (VALUES (Orders [Category]),"Category1”,


COUNTROWS(Orders)), Orders [Category]="Furniture")

It returned 2121 and the returned digit is correct.

CALTBLA2 = FILTER (ADDCOLUMNS (VALUES (Orders [Category]),"Category1”,


COUNTROWS(Orders)), Orders [Category]="Furniture")

It returned 9994 and the number returned is incorrect. This number is not the number of Furniture
category products, but the number of all category products!

In the first expression we wrote with CALCULATETABLE, condition is running first! Therefore, there
are only Furniture products in the table that both ADDCOLUMNS and VALUES see. It even -according
to this example- VALUES (Orders [Category]) sees the single line “Furniture” table. That's why it
calculates 2121 without the need for a context transition.

In the version we wrote with FILTER, before ADDCOLUMNS and group VALUES are working. The
category column that VALUES sees has all categories, including Furniture. When he counts the
products under all categories, he finds 9994. FILTER's condition only takes effect after this calculation
has been made. It remains Furniture in category. However, since we did not make a "context
transition" in the formula we wrote, it continues to count all the products. For this statement to
work correctly, we need to call COUNTROWS with CALCULATE.

CALTBLA2 = FILTER (ADDCOLUMNS (VALUES (Orders [Category]),"Category1”,


CALCULATE(COUNTROWS(Orders))), Orders [Category]="Furniture")

** Here for ADDCOLUMNS and context transition!

total Sales = Orders [Sales]*Orders [Quantity] (NEW COLUMN)

total Sales_m = sumx (Orders, Orders [Sales]*Orders [Quantity]) (MEASURE)

max sales = maxx (Orders, [total Sales_m])

max_prod_sales = Maxx (values (Orders [Product Name]), [total Sales_m])


max_prop_sales_wo_m = maxx (Orders, sumx (Orders, Orders [Sales]*Orders [Quantity]))

max_prop_sales_wo_m1 = MAXX (VALUES (Orders [Product Name]), sumx (orders, Orders


[Sales]*Orders [Quantity]))

max_prop_sales_wo_m2 = MAXX (VALUES (Orders [Product Name]), CALCULATE (sumx (Orders,


Orders [Sales]*Orders [Quantity])))

Remember:

1. measures inside function automatically converts into an expression with CALCULATE.

max_sales = Maxx (Orders, [total Sales_m])

max_sales = MAXX (Orders, CALCULATE (sumx (Orders, Orders [Sales]*Orders [Quantity])))

2. max sales = maxx (Orders, [total Sales_m])


from table visual,
first apply year, month filters on Orders table row by row and calculate total sales.
3. max_prod_sales = Maxx (values (Orders [Product Name]), [total Sales_m])
from table visual,
 first apply year, month filter on Orders table row by row. (means after applying year,
month filters first we get Jan 2011 data).
 Second get the distinct product names as single column table from complete Orders
table.
 After that, calculate total sales value from each row of distinct product name.
 After that, get the maximum amount value.

Remember from above 2 & 3 steps: we get different values.

I have added one duplicate record in Orders table only I update ID column value. (in 2011
Jan month).

In the Max Sales calculation, [total Sales_m] measure calculate based on each row by row of
Orders table records of after apply year, month filter data. We get below Order data with

Total sales.
Using the above table, we get maximum value of total sales value. (that’s why we are getting rowing
value 23164.38, not getting 46328.76 value.)

After that get the maximum value.

In the max_prod_sales calculation,

I. Get orders table with applied filters year, month.


II. get the distinct product names as single column table from complete Orders table.
III. Apply each row product name filter on Order table data (point 1 data).
IV. After that we get product name wise sum of sales value. Like below table.

Product Name Sales value


Product1 xxxxx
Product2 yyyyy
V. From the above table, we get maximum value.

4. max_prop_sales_wo_m = maxx (Orders, sumx (Orders, Orders [Sales]*Orders [Quantity]))


why we get different result compare to above option 2,3 (max sales, max_prod_sales).
I. First apply year, month filter on Orders table.
II. Using the filtered Orders table, we get sum of sales and quantity product value as
scalar value.
III. Maxx function work on Single sum value.
IV. Remember Orders table inside maxx function having no use in this case.

5. max_prop_sales_wo_m = maxx (Orders, CALCULATE (sumx (Orders, Orders [Sales]*Orders


[Quantity])))
I. First apply year, month filter on Orders table.
II. Filtered Orders table as taken as new table in Place of Orders table parameter in side
maxx.
III. Calculate sum of sales and quantity product value using every row by row of newly
created filtered Orders table.

IV. Maxx function work on above table total sales column value.
ISBLANK () VS BLANK ()

Remember:

When we import excel file into PowerBI, all empty string columns are taken as null.

When we import sql server database table data into PowerBI, empty string columns are
taken as empty and NULL column values are taken as null.

ISBLANK (null) function returns true.


ISBLANK (empty string) function returns false.
Column value =BLANK () return true when column value is either empty string or null value.

OR

OR

Remember: Add Zero (0) value to calculate expression only it returns


number value. Otherwise we get an error (suppose returns string value)
Understanding the DAX Filter Function
FILTER(<table>, <filter>)
Returns a table that represents a subset of another table or expression.

1. The first argument, i.e., Table, accepts a physical or a virtual table to Filter.
 A physical table can be seen in the data model.
 A virtual table is the one created on the fly.
2. The second argument, i.e. Condition accepts a logical test that is performed in each row of the
table.
 All rows that satisfy the condition, i.e. return TRUE are kept while other rows are removed.
 Keep in mind the condition must return a True or False output else it stands invalid.
FILTER Function used on a Virtual Table
Sales was a physical table present in the Data Model, let’s see if we can apply the FILTER function to
a table that doesn’t physically exist i.e. a Virtual Table.

Let’s solve this Question – Get a table of dates where the sales amount is >= $50000. Consider this
DAX for creating a Table.

FILTER Function used in a Measure

SUM VS SUMX flow:


DAX SYNTAX

The DAX syntax is made up of different elements and when combined results in the following
formula.

1. Name of the measure, Total Sales


2. Equal sign operator (=) shows the start of the formula and will return a result when calculated
3. The DAX function SUM adds all the numbers in the Sales [Unit Price] column.
4. () surrounds the expression with one or more arguments, the argument provides the value to a
function
5. This is the table that is referenced, Sales.
6. This indicates the reference column [Unit Price], the column to aggregate to a SUM, in the Sales
table.

SUM
Let’s start with SUM. Most of you know what SUM is, if you’ve ever used Excel or some
other software programs, SUM comes quite naturally. We understand SUM adds up all the values in
a column, and because of this the SUM syntax requires a column as input.

SUM(<column>)

In order to see how this function operates, let’s create a new measure. Let’s say that we want to
calculate the value of all our individual items sold. We will call our measure SUM and we’ll SUM the
column ‘Total Sales’ from our ‘Sales’ table. SUM is going to look at the ‘Total Sales’ column in the
‘Sales’ table and sum all the values together.

SUM = SUM (Sales [Total Sales])

Let’s use a matrix visual to display the measure ‘SUM’ by ‘ITEMNAME’. To do this, we add
‘ITEMNAME’ as the row value and ‘SUM’ as our values in Power BI. Here we can see that SUM does
exactly what we expect it to do. It will sum the values for each ‘ITEMNAME’ in the table together and
return us a Total at the bottom. This total is the Total value for ‘SUM’ of all the ‘ITEMNAMES’.

SUMX
Let’s create a new measure now to see how the function SUMX operates. The first notable
difference for SUMX is that you need to provide the table name and an expression, so SUMX returns
the sum of an expression evaluated for each row in the table. The term <table> contains the rows for
which the expression will be evaluated, and the term <expression> evaluate each row of the table

SUMX(<table>, <expression>)

In other words, let’s say we want to determine the Total sales for each unit, we will have to choose
the ‘Sales’ table, and, in the ‘Sales’ table, we have two values, quantity of units sold ‘QTYNET’ and
the unit price ‘Unit Price’ that must be multiplied to determine the Total sales for each unit.

SUMX = SUMX (Sales, Sales [QTYNET]*Sales [Unit Price])

Let’s add the measure to our canvas and immediately we see it does the same thing, it sums the
Total sales for each item.
So, the difference here is that SUMX goes to each row in the table and it says multiply the quantity
by the unit price and then give us the Total sales amount and does that iteratively for each row in
the table and once it reaches the bottom it does a sum and adds up all those values together. SUM
on the other hand basically multiplies the two values together. So, a good comparative example is
where SUM would be ten times ten and SUMX would be 10 + 10 + 10 + 10, 10 times. Ultimately, they
get to the same amount but that’s the difference in how these two functions operate. Because of
that SUMX is not as efficient as SUM, but depending on your situation, it may give you the ability to
do a little more.

CALCULATE
If you are new to DAX, the SUMX and SUM measures that we just created can be used in other DAX
calculations. What I mean is that you can use one measure within another measure, and we will do
that now when we get to the CALCULATE function. The CALCULATE function requires an
<expression> and a comma separated list of Booleans (true or false statements) expressions,
defining one or more <filters>, which is optional to fill in.

CALCULATE gives us the syntax below:

CALCULATE(<expression>, <filter1>, <filter2>…)

In this expression you can do one of two things when you want to do a SUM of the Sales and then
apply a filter. You will be able to use either an existing created measure such as the SUM or SUMX
that we have just created, or alternatively you will need to apply the SUM or SUMX function in the
expression referencing the table ‘Sales’ and column ‘Total Sales’ as below.

CALCULATE = CALCULATE (SUM (Sales [Total Sales])

You could do as in the above formula, but best practice for DAX would be to build on top of the
previous measures that you have created. In this case, I am going to use the SUM measure that I
have already obtained and apply a filter to that measure. So, for example, let’s say that we want a
table like the one that we have created, but we don’t want to see the values for all items. We want
to filter this table by a customer name. In order to filter by the customer name ‘ACME Plumbing’, we
take the column ‘CUSTOMERNAME’ from the ‘Customers’ table where it equals ‘ACME Plumbing’.

Great, let’s see the formula for this measure below:

ACME Plumbing = CALCULATE([SUM], Customers [CUSTOMERNAME]=” ACME Plumbing”)


Let’s add this measure to our canvas. We see a much shorter list of item names because of the filter
we’ve applied to this calculation. This list only sums the values of items where the filter for
‘CUSTOMERNAME’ is ‘ACME Plumbing’.

Another example would be to say that we want to calculate the Total Sales for two companies called
‘ACME Plumbing’ and ‘Custom Comfort’. This can be done in the same way as we did previously
when calculating the Total Sales for ‘ACME Plumbing’. Let’s do this same measure now for ‘Custom
Comfort’.

Custom Comfort = CALCULATE([SUM], Customers [CUSTOMERNAME]=” Custom Comfort”)

Let’s add the measure to our canvas.

Now, we can add ‘ACME Plumbing’ and ‘Custom Comfort’ to one table.

Wow, we can see what’s happening here. This table shows the combined sales and items sold for
both companies ‘ACME Plumbing’ and ‘Custom Comfort’ above.

Congratulations! This is the first step in the process of becoming a master in DAX. It is a journey not a
destination, so stick with us and we will continue showing you how these calculations work.

Filter execution flow:


CASE 1:

Its automatically converts to Sales = CALCULATE (SUM (Sales [Total Sales]))

If we look at the Sales table from the Data view pane, we can see what it has done is to filter on the
CUSTOMERNAME for each row in the table, which is the outer filter context.

CASE 2:

Let’s do another measure. I want to do the sales amount where the sales quantity is greater than
100. For ease of reference, I’m going to call it ‘Sales quantity > than 100’.

I want to do a CALCULATE of the sales measure we created earlier called ‘Sales’ where the sales
quantity is greater than 100.

If we look at the Sales table from the Data view pane, we can see what it has done is to filter on the
CUSTOMERNAME for each row in the table (ACME Plumbing for example), which is the outer filter
context.
Then it goes to the inner filter context (inside the DAX CALCULATE function) where it takes the
quantity column and applies a filter where the sales quantity is greater than 100.

It then sums up the total sales together to give us an answer for each of the CUSTOMERNAMEs.
CASE 3:

I want to do a similar calculation than before where I’m going to calculate the total sales where the
quantity again is greater than 100. But this time I’m going to use SUMX instead of SUM, so let’s see
how that works.

Start with CALCULATE and use a SUMX of the ‘Sales’ table and multiply the Sales [Unit Price] by the
Sales [QTYNET] (the Quantity) and then finally let’s include a filter where the Sales [QTYNET] > 100.
Format to British Pound and let’s put it on the canvas.

Okay great so it seems like it does the same thing, right?! We can see that the answer from
our SUM and from the SUMX is the same. The difference with SUMX and SUM is in the way it
evaluates.

So for each row where it finds a quantity larger than 100, it will calculate the Sales[Unit
Price] * Sales[QTYNET] and store that value, and once it has reached the bottom of our table, it will
SUM all those values together and return the answer.

CASE 4:

let’s do another measure where the sales quantity is greater than 100, but this time I want to add a
few other interesting functions into our calculation.

Let’s do a CALCULATE, where we SUM the Sales [Total Sales] but in this case let’s add a FILTER
function and the ALL function.
So, we’re gonna FILTER ALL values from the Sales table where the Sales [QTYNET] is greater than
100. Let’s call the measure Sales Quantity > 100 equiv (for equivalent of the previous measure).

The FILTER function as we know will return a filtered table, and the ALL function will force ignore all
outside filter context and apply the expression on ALL items where Sales [QTYNET] is greater than
100.

If we add the measure to our canvas, we can see it returns the same answer still. If we look at our
two measures we have the first one which is just a normal CALCULATE where we added a filter
where the quantity is larger than 100.

For our second measure, we used we did the same thing but instead of SUM we used SUMX to get
us the same value and in the last one we’ve now said CALCULATE the SUM of Sales[Total Sales] but
before we do that FILTER the Sales table and return ALL values irrespective of our outside filter
context where it will force the calculation to return the entire table and then filter it where the Sales
quantity is greater than 100.

Okay great so we have three separate calculations which are different yet provides us the exact
same answer and they get to that answer in slightly different way. Let’s use another few examples
and that I want to use just to explain how and these other calculations will work if we actually apply
an outer filter context.

For the first measure I want to do the total sales for the customer called “The Courtyard”.

So, I want to filter all cells with a customer name that is equal to “The Courtyard”.

Start with a SUMX and add the FILTER function of the Sales table and then also apply the RELATED
function where it fetches the value from a related table (Called Customers) and I want to go and find
the customer name from customers table where it’s equal to “The Courtyard”.

Finally, we want to be able to do the Sales [Unit Price] multiplied by the Sales [QTYNET].
Drag it onto the canvas and we can see that now it has returned a value, but only for “The
Courtyard”.

Note: Remember that SUMX is an iterator, so it goes through each line in the table and CALCULATES
the Sales [Unit Price] multiplied by the Sales [QTYNET], but before it does so it finds the “The
Courtyard” value from the RELATED Customers table, and applies the FILTER in the CUSTOMERNAME
column.

Note that RELATED can only work if there is a relationship between the Sales and Customers table.

Let’s do another measure, but this time we’ll use CALCULATE with the [Sales] measure we already
created previously.

Remember that when we use CALCULATE we can either do a SUM of the Sales [Total Sales] or use an
existing measure called [Sales] which already calculates a SUM (Sales [Total Sales].

To continue with our formula, let’s CALCULATE the [Sales] and we want to filter the
CUSTOMERNAME from the Customers table where the value is equal to “The Courtyard”.
Finally lets formatted to British Pound and add it to our canvas.

It seems like it’s given the same answer as with our previously used RELATED function inside of the
Sales (The Courtyard) measure.

Before we test adding an outer filter context, I would like to add one more measure.

So as an introduction to the ALL and FILTER functions and how they work with the CALCULATE
function, lets create a measure called ‘Sales (The Courtyard) CALCULATE_FILTER_ALL’.

For this measure I want to CALCULATE again of the [Sales] measure, let’s use the FILTER function of
ALL items in the Sales [CUSTOMERNAME] column and finally filter the Sales [CUSTOMERNAME] table
to only include items that belong to “The Courtyard”.

So, before it CALCULATEs the [Sales] measure, it first applies the FILTER context. It starts with the
FILTER function, returns ALL values from the Sales [CUSTOMERNAME] column (This actually returns a
unique list of the values from the Sales [CUSTOMERNAME] column) and then filters the column
values to only include “The Courtyard”.

Then it CALCULATES the [Sales] measure and returns the answer. Again lets add it to the canvas and
format to British Pound.
Interesting, so it returns a value for every single customer but which is equal to “The Courtyard”. In
this case it actually forces it with ALL and the internal filter context to ignore the outer filter context.

You might also like