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

Power BI Modeling with DAX

Uploaded by

sai Charan
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
31 views

Power BI Modeling with DAX

Uploaded by

sai Charan
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 47

Microsoft Power BI - Power Pivot Modeling

Power BI Modelling is used to model data on top of cleansed data. Model should contain
Fact table(s) and Dimension tables. Most of the dimension tables will be having
relationships with Fact table(s).
Star Schema: If the dimension table(s) are directly related to Fact table, then we can
call it as Star Schema OR If fact table is surrounded by dimension tables and having
relationship, then we can call it as Star Schema
 Star Schema contains Dimension table(s) and Fact table
 All facts are measurable. Every fact in Fact table is number but all numbers are not
facts.
 Fact table contains more amount of data and Dimension tables contain less amount of
data.
 Star Schema improves the performance because of less number of joins.
Snowflake Schema:
Integrated Schema: It's combinations various schema with following combination
i. Star + Star
ii. Star + Snowflake
iii. Snowflake + Snowflake
Note: There should be min two fact tables and there is a chance to have shared dimension
tables across various Fact tables.

Shared/Confirmed Dimension: If the Dimension table is shared by multiple fact tables then
we can call it as Shared Dimension.
Ex: In the schema, DimDate, DimProduct and DimStore are the shared dimensions
Implementing/Creating Integrated (Snowflake + Star+ Snowflake)
When you import data from Data Sources into Power BI Desktop, it will create relationship
automatically. Sometimes, this feature is acceptable and if you have more number of tables
and if requirement changing frequently to add new dimension tables at the development,
then creating auto relationship is very dangerous operation.

To avoid above problem, we can switch OFF(Uncheck) Auto Detecting relationships in Power
BI and relationships will be created by manually by using "Manage Relationships"

To create relationship between two tables, we don't required Primary Key and Foreign Key
but we need common columns and should have similar kind of data
Practical Note

To keep measures, let's do the following activities


Create an empty table in Power BI to keep Measures.
Create a measure in "Sales(Measure Group)" table (Sales Amount)
Hiding a column from the table or hide complete table

Load the data from ContosoRetailDW for the following tables as per Star Schema.
1. FactSales(Not required, if it is loaded)
2. DimDate
3. DimStore
4. DimChannel
5. DimPromotion
6. DimCurrency
To split the data across various dimensions level, then we need to make relationships
otherwise, we can see duplicated data (same numbers for all levels)
To create relationships between Fact and Dimension tables, we need to use the following
types of Cardinalities.

1. Many - to - One (* : 1 ) : It is used to create a relationship from Many records to Single


record. Ex: Relationship between Fact and DimDate
2. One - to - Many (1 : * ) : It is used to create a relationship from Single record to
Multiple records. Ex: Relationship between DimDate and Fact
3. One - to - One (1 : 1 ) : It is used to create a relationship from One record to One
record.
4. Many - to - Many (* : * ) : If the many records are related to many records, then we
can use this type of relationship.
Instead of creating relationships by using drag and drop, we can use Manage relationships

Manage Relationship: It is used to add new relationship, modify/edit relationship


and to remove relationship from Model.
Create Relationship between DimChannel and FactSales tables by using Manage
Relationship
Note: Hide all the key column from all the tables, no need to show key columns in the report
view and hide columns which are not required to show to the user.

To handle or to create some custom calculations on top of Power BI Modelling, we need to


write DAX Expressions.
Creating Relationships as Per Star Schema

Create the following measure in Sales table


Sales Amount = SUM(FactSales[SalesAmount])
Total Cost = SUM(FactSales[TotalCost])

Note: If you are using any column which is not required to show to the user then hide it.
Take required columns from the Source to Power BI.

Loading DimProductDetails Table as per Star Schema by writing SQL Script

Loading DimProduct, DimProductSubcategory and DimProductCategory tables and join


them to get data as per DimProduct table in the Star Schema

Implementing Snowflake Schema:


1. Reuse Star Schema and remove DimProduct table
2. Add the following tables into Snowflake Schema
a. DimProduct
b. DimProductSubcategory
c. DimProductCategory
3. Create Relationships as per Snowflake Diagram
Implementing Integrated Schema (Star + Star, Snowflake + Snowflake, Star + Snowflake)
1. Reuse Star or Snowflake schema
2. Add the following table into Model
a. FactOnlineSales
b. DimCustomer
3. Create Relationship with possible dimension tables as requirement
Data Analysis eXpression
We can create DAX (Data Analysis eXpression) Expression with the help of various functions,
Operators and datatypes.

DAX DATA TYPES:


Whole Number (Integer) : It is used to store integer values. It can store up to 64-bit value.
Decimal Number (Float) : It is used to store a double-precision floating point value.
Currency (Currency) : It is used to store a fixed decimal number.
Date(DateTime): DAX stores dates in a DateTime data type.
Now() +1
Boolean(TRUE/FALSE): The Boolean data type is used to express logical conditions.
Text(String): Every string in DAX is stored as Unicode String, where each character is stored
in 16 Bits. By default, the comparison between two strings is case-insensitive.

RUDRA = rudra ---> Both are equal


Binary large Objects (BLOB) : It is used to store images in the Data Model and it is not
accessible in DAX. It is being used by client tools like Power BI, SSRS and so on…

DAX Operators:
DAX Functions
1. Mathematical Functions
2. Text Functions
3. Date & Time Functions
4. Information Functions
5. Aggregate Functions
6. Logical Functions
7. Parent - Child Hierarchy Functions
8. Time Intelligence Functions
Note: Get Employee/Department Data from Database(ContosoRetailDW) into Power BI

What is New Column ?


It is used to create column for table by using DAX(Data Analysis Expression)
Definition of Column will be applied for each and every row of the table
It stores the data physically in table so it takes some space
Columns will be Row Level Context
It is specific to the table. We can't use/call in other table
Mathematical Functions: These functions are used to handle numerical data
ABS(Number): It is used to get absolute of a number.
Create a new Column by using this definition Sal-2850
 Salary = Employee[SAL] - 2850
 ABS = ABS(Employee[Salary])

DIVIDE(<numerator>, <denominator> [,<alternateresult>])


Performs division and returns alternate result or BLANK() on division by 0.

DivisionOperator = 25/5
DivisionOperator = 25/0

Divide = DIVIDE(25,5)
Divided = DIVIDE(25,0)

Note: If alternateresult is not provided when there is an error, then it will be taken BLANK()
by default. We can pass value also

Task: Crete a column to get Sal/Comm


Sal/Comm = Employee[SAL]/Employee[COMM]
Sal/Comm = DIVIDE(Employee[SAL],Employee[COMM],2)
Note: If there is comm is blank, then division is not possible, so handle blank with IF
function To get Correct result, we need to use either If statement or Case statement
IF(<LogicalTest>, <ResultTrue>, <ResultFalse>)
It is used to check the condition, if the Condition Succeeded, then ResultTrue will be
returned else ResultFalse will be returned
It takes only two conditions, if we have N number of conditions, then we need to N-1 IF
functions. It returns Boolean datatype either True or False
It is equivalent to if statement in Power Query
IsBlank(<ColumnName>)
It is used to check whether the column is having blank or not. If the column is having Blank,
then it returns True else False

Create a new column to show True, if the commission is having blank else False
IsBlank = ISBLANK(Employee[COMM])

Create a new column to show 1, if the commission is Blank or Zero


Check1 = IF(ISBLANK(Employee[COMM]) || Employee[COMM] = 0, 1, 0)
Salary/Comm = DIVIDE(Employee[SAL],
IF(ISBLANK(Employee[COMM]) || Employee[COMM] = 0, 1, Employee[COMM])
)
EVEN(Number): Returns number rounded up to the nearest even integer.
Even1 = EVEN(1.5)
Even2=EVEN(3)
Even3=EVEN(2)
Even4=EVEN(-1)

INT(<number>)
Rounds a number down to the nearest integer.
INT = INT(1.5) -->1

POWER(<number>, <power>)
Returns the result of a number raised to a power.
Power = POWER(5,2)
ROUND(<number>, <num_digits>)
Rounds a number to the specified number of digits.
Round1 = ROUND(2.15,1)
Round2 = ROUND(21.5,-1)
Note:
 If num_digits is greater than 0 (zero), then number is rounded to the specified number
of decimal places.
 If num_digits is 0, the number is rounded to the nearest integer.
 If num_digits is less than 0, the number is rounded to the left of the decimal point.
Salary = Employee[SAL]/5.3
Round3 = ROUND(Employee[Salary], 2)
Round4 = ROUND(Employee[Salary], -2)
ROUNDDOWN(<number>, <num_digits>)
It is used to round a number down, towards 0 (zero)

RoundDown1 = ROUNDDOWN(3.14159,3)
RoundDown2 = ROUNDDOWN(31415.92654, -2)
SalaryDown3 = ROUNDDOWN(Employee[Salary], 2)
SalaryDown4 = ROUNDDOWN(Employee[Salary], -2)
ROUNDUP(<number>, <num_digits>)
Rounds a number up, away from 0 (zero).
SalaryUp1 = ROUNDUP(3.14159,2)
SalaryUp3 = ROUNDUP(Employee[Salary], 2)
SalaryUp4 = ROUNDUP(Employee[Salary], -2)
SIGN(<number>)
The function returns 1 if the number is positive, 0 (zero) if the number is zero, or -1 if the
number is negative.
Sign = SIGN(Employee[Salary])
SQRT(<number>)
Returns the square root of a number.
SQRT = SQRT(9)
TEXT FUNCTIONS
These function are used to handle text information. Most of the functions will
take strings, numbers and return strings but some of the functions will return
numbers

BLANK()
Returns a blank. Blanks are equivalent to nulls

Task: Create a new column to show blank, if the department name is Sales else
show as it is

Blank = IF(Department[DNAME] = "Sales", BLANK(), Department[DNAME])


UNICODE(text)
Returns a numeric code for the first character in a text string.
UniCode = UNICODE("A")
UniCodeA1 = UNICODE("a")
UnicodeDName = UNICODE(Department[DNAME])

UNICHAR(Number)
Returns a character for the given number.
UniChar = UNICHAR(65)

Task: Create a new column to show character space with DAX expression
Unichar Space = UNICHAR(32)

Task: Create a new column to show character star with DAX expression
Unichar Star = UNICHAR(9733)

Create a column with the following value


"Rudra Soft" is training institute

COMBINEVALUES(<delimiter>, <expression>, <expression>[, <expression>]…)


The COMBINEVALUES function joins two or more text strings into one text string.

Task: Create a new column to show FullName by using First Name and Last Name
Full Name = COMBINEVALUES(" ",
DimCustomer[FirstName],
DimCustomer[LastName]
)
Task: Can you use custom value in CombineValues function ?

CombineValues = COMBINEVALUES(",",
Department[DNAME],
Department[LOC],
"USA"
)

Task: Create a new column to show Full Name by using FirstName, Middle Name and Last
Name in DimCustomer and validate the data

Task: Create a new column to show the Short Month with the following format in Employee
table
Oct-2019

Task: Create a new column to show with following format


October,2019

CONCATENATE(<text1>, <text2>)
Joins two text strings into one text string.
CONCATENATE = CONCATENATE("Hello", "World")

Concatenate = CONCATENATE(
CONCATENATE("Hello", " "),
"World"
)

Task: Create a new column to show FullName by using First Name and Last Name

FullName = CONCATENATE(DimCustomer[FirstName], DimCustomer[LastName])


Full Name = CONCATENATE(
CONCATENATE(DimCustomer[FirstName], " "),
DimCustomer[LastName]
)

Note: The CONCATENATE function in DAX accepts only two arguments, whereas the Excel
CONCATENATE function accepts up to 255 arguments. If you need to add more arguments,
you can use the ampersand (&) operator.

FullName2 = DimCustomer[FirstName] & " " & DimCustomer[LastName]


CONCATENATEX(<table>, <expression>, [delimiter])
Concatenates the result of an expression evaluated for each row in a table.
ContenateX = CONCATENATEX(Department,
Department[DNAME],
"*"
)

ContX = CONCATENATEX(Department,
Department[Dname] & " is located in " & Department[Loc],
"*"
)
Task: Having report with Slicer Product Category, When user selected "Audio" then we need
to show "Audio" or if the user selected "Audio" and "Computers", then we need to show
Audio, Computers to make sure what user selected values.

SELECTEDVALUE(<ColumnName>, [AlternativeResult])
It is used to get selected value from the specified column
Task: Create a measure to show selected value from the slicer in the Report.
Selected =
SELECTEDVALUE(ProductDetails[ProductCategoryName], "All")

LOWER(<text>)
Lower(<Text>): It is used convert all the characters into lowercase. It returns text
Ex: Lower("RAMA") -->rama

Task: Create a column to show all employee names into lowercase

UPPER (<text>)
Upper(<Text>): It is used convert all the characters into Uppercase. It returns text
Ex: Upper("rama") -->RAMA

Task: Create a column to show Customer FirstName in Uppercase

LEFT(<text>, <num_chars>)
Left(<Text>, <No: Of Characters>): It is used to get the characters from starting(left) position
with specified number of characters

Ex: Left("Rama", 1) --> R


RIGHT(<text>, <num_chars>)
Right(<Text>, <No: Of Characters>): It is used to get the characters from ending(Right)
position with specified number of characters

Ex: Right("Rama", 1) --> a

LEN(<text>)
Len(<Text>): It is used to get complete length of text. It returns number
Ex: Len("Rama") --> 4

Task: Create a new column to show employee names in lower case, if the names starts with
S else show in upper case

Task: Create a new column to show employee names in lower case, if the names starts with
S or J else show in upper case

MID(<text>, <start_num>, <num_chars>)


Mid(<Text>, <Starting Position>, <No: Of characters>): It is used to get range of characters
from starting position with specified number of characters.

Ex: Mid1 = Mid("Rama", 2,1) --> a


Mid 2= Mid("Rama", 1,1) --> R

Note: Index will start from 1 where as in Power Query index will start from 0

Search(<FindText>, <WithInText>, <StartingPosition>, [<NotFoundValue>]):


It is used to find the position of specified character with in the specified text from starting
position. It returns number. This functions in not case-sensitive

Ex: Search("m", "Rama", 1, 0) --> 3


Search("b", "Rama", 1, 0) --> 0

It is equivalent to CharIndex function in SQL Server and Text.PositionOf in Power Query

Find(<FindText>, <WithInText>, <StartingPosition>, [<NotFoundValue>]):


It is used to find the position of specified character with in the specified text from starting
position. It returns number. This functions is case-sensitive
Ex: Find("M", "Rama", 1, 0) --> 0
Find("a", "Rama", 1, 0) --> 2

It is equivalent to CharIndex function in SQL Server and Text.PositionOf in Power Query


Task: Create a new column to find position of C from Department Name
Search C = SEARCH("C", Department[DNAME], 1, 0)

Note:
1. NotFoundValue should be number datatype & Boolean data type
2. Always recommended to pass constant value, if not found.

Task: Create a new column to find position of space from FullName in DimCustomer

Task: Modify above task to get before position of space

Task: Create Expression to get First Name from Full Name?

Create Expression to get Last Name from Full Name with / without using Mid

First Name = MID(EmpDetails[Full Name], 1, EmpDetails[SpacePosition])


FirstName = LEFT(EmpDetails[Full Name], EmpDetails[SpacePositionMinusOne])

What is Variable ?
Variables are used to store values temporarily. We can assign the values and we can also
modify values dynamically by writing Expressions

If there is complex logic in the Business definition, then we can split it into pieces to
understand easily.

Variables provides flexibility to maintain DAX script.


Maintenance is easy.

Using Variable in DAX

Without variable
First = MID(DimCustomer[Full Name], 1,
SEARCH(" ", DimCustomer[Full Name], 1, 0)-1
)
With variable
First Name =
VAR vName = EmpDetails[Full Name]
VAR vSpacePosition = SEARCH(" ", vName,1)-1
RETURN
MID(vName, 1, vSpacePosition)
Create Expression to get Last Name from Full Name
Without variable

With variable

Create Expression to get Last Name from Full Name, if the full name is not having delimiter.
How can you handle it (Hint: If name is having only one name or no delimiter)
Last Name =
VAR vSpacePosition = FIND(" ", EmpDetails[Full Name], 1)
VAR vLen = LEN(EmpDetails[Full Name])
RETURN
MID(EmpDetails[Full Name], vSpacePosition+1, vLen-vSpacePosition)

Last Name =
VAR vSpacePosition = FIND(" ", EmpDetails[Full Name], 1)
VAR vLen = LEN(EmpDetails[Full Name])
RETURN
RIGHT(EmpDetails[Full Name], vLen-vSpacePosition)

REPLACE(<old_text>, <start_num>, <num_chars>, <new_text>)


REPLACE replaces part of a text string, based on the number of characters you specify, with
a different text string.

Create a column to replace "**" in place of space in the Full Name

Replace =
REPLACE(EmpDetails[Full Name],FIND(" ", EmpDetails[Full Name], 1), 1, "**")

Create a column to replace "**" in place of space in the Full Name by using variables

Replace =
VAR vSpacePosition = SEARCH(" ", EmpDetails[Full Name], 1)
VAR vName = EmpDetails[Full Name]
RETURN
REPLACE(vName, vSpacePosition, 1, "**")
SUBSTITUTE(<text>, <old_text>, <new_text>, [<instance_num>])
Replaces existing text with new text in a text string

Task: Substitute space with ** for Full Name

Note: Replace function replaces the text for the specified position where as Substitute
function can replace the text in all the place where it found.

REPT(<text>, <num_times>)
Repeats text a given number of times. Use REPT to fill a cell with a number of instances of a
text string.
Note:
 If num_times is 0 (zero), REPT returns a blank.
 If num_times is not an integer, it is truncated.
Note: The result of the REPT function cannot be longer than 32,767 characters, or REPT
returns an error.
Replicate 1 = REPT(DimCustomer[FirstName], 2)
Replicate 2 = REPT(DimCustomer[FirstName], 0)
Replicate 3 = REPT(DimCustomer[FirstName], 2.6)

Task: When you use replicate, if you want to provide space for each replicate, then How can
you provide ?

Replicate 4 = REPT(DimCustomer[FirstName] & " ", 2.6)


Len = LEN(DimCustomer[Replicate 4])

Note: We need to remove last space for every name for Replicate 4

TRIM(<text>)
Removes all spaces from text except for spaces between words
Trim = TRIM(DimCustomer[Replicate 4])
Len after Trim = LEN(DimCustomer[Trim])

VALUE(<text>)
Converts a text string that represents a number to a number.
VALUE = VALUE("5")

EXACT(Colum1, Column2): It is used to compare two strings row by row. If both strings are
equal, it returns TRUE else it returns FALSE
Note: It is case sensitive.
Exact 1 = EXACT("a", "A")
Exact 2 = EXACT("a", "a")
Task: Create a new column to check whether Job is having SALESMAN or not?
EXACT = EXACT(EMP[JOB], "SALESMAN")

Task:
Can you do above task with the help of IF function and write the difference between IF and
EXACT functions

If Exact = IF(Employee[JOB] = "SALesman", TRUE(), FALSE())


If Exact 1 = IF(Employee[JOB] = "SalesMan", "Yes", "No")
If Exact 2 = IF(Employee[JOB] = "SalesMan", 1, 0)

FORMAT(<value>, <format>): It is used to format numbers, Dates and Time

Task: Create a column to show numbers with $, if the number is +ve, then show $123 else
show ($123)

Format = FORMAT(Employee[Salary], "#,##0")

Format 1 = FORMAT(Employee[Salary], "$#,##0")

Format 2 = FORMAT(Employee[Salary], "$#,##0;($#,##0)")


DATE FUNCTIONS
These functions are used to handle Date and Time information. If you have Date and Time,
we can get the parts of the Date and Time with these functions
DATE(<year>, <month>, <day>)
Returns the specified date in datetime format.
Date = DATE(2019, 1, 1)
CALENDAR(<start_date>, <end_date>)
Returns a table with a single column named “Date” that contains a contiguous set of dates.

Creating table with DAX Expression


Cal = CALENDAR (DATE (2020 1, 1), DATE (2020, 12, 31))
Calendar = CALENDAR("2020-01-01", "2020-12-31")

Create a view by taking data from ContosoRetailDW and then load the data into Power BI
Model, show the data(Sales Amount) by Year, Month Name

CREATE VIEW vFactSales AS


SELECT
DateKey,
p.BrandName,
SUM(SalesAmount) AS SalesAmount
FROM FactSales f INNER JOIN DimProduct p ON f.ProductKey = p.ProductKey
GROUP BY DateKey,
p.BrandName

Create the following tables with DAX in Modeling


Calendar = CALENDAR(MIN(vFactSales[DateKey]), MAX(vFactSales[DateKey]))
Product = DISTINCT(vFactSales[BrandName])

CALENDARAUTO([fiscal_year_end_month])
Returns a table with a single column named “Date” that contains a contiguous set of dates.
Fiscal Cal = CALENDARAUTO(3)

Note: CalendarAuto function will take year from lowest date in the entire model to create
fiscal calendar.

DATEVALUE(date_text)
Converts a date in the form of text to a date in datetime format
DataValue=DATEVALUE("1/1/2019")
NOW()
Returns the current date and time in datetime format
Now = NOW()
TODAY()
Returns the current date.
TODAY = TODAY()
YEAR(<date>)
Returns the year of a date as a four digit integer in the range 1900-9999.
Year = YEAR('Calendar'[Date])
MONTH(<datetime>)
Returns the month as a number from 1 (January) to 12 (December).
Month Nbr = MONTH('Calendar'[Date])

Note: If you want to see month name(Parts of the date) in place of Month Nbr, then we
need to use SWITCH function to control it, we can use hierarchal functions and Format
function
Month Name = SWITCH(
'Calendar'[Month Nbr], 1, "Jan",
2, "Feb",
3, "Mar",
4, "Apr",
5, "May",
6, "Jun",
7, "Jul",
8, "Aug",
9, "Sep",
10, "Oct",
11, "Nov", "Dec"
)
Note: To show month names in calendar order in the report, then we need to do sorting
month name by month number
Select Month Name --> Click on Sort by Column --> Select Month NBR column and observe
the output in the report
Note: Instead of above expression, we can use the following expression to get month name
as it is above result

Date = 'Calendar'[Date].[Date]
Day = 'Calendar'[Date].[Day]
MonthName = 'Calendar'[Date].[Month]
Month = LEFT('Calendar'[Date].[Month],3)
MonthNo = 'Calendar'[Date].[MonthNo]
QuarterName = 'Calendar'[Date].[Quarter]
QuarterNo = 'Calendar'[Date].[QuarterNo]
Year = 'Calendar'[Date].[Year]
Short Month =
LEFT('Calendar'[Date].[Month], 3) & "-" & RIGHT(YEAR('Calendar'[Date]),2)
DAY(<date>)
Returns the day of the month, a number from 1 to 31.
Day1 = DAY('Calendar'[Date])
Day2 = 'Calendar'[Date].[Day]

WEEKNUM(<date>, <return_type>)
Returns the week number for the given date and year according to the return_type value.
The week number indicates where the week falls numerically within a year.
Return type: 1, week begins on Sunday. Weekdays are numbered 1 through 7.
Return type: 2, week begins on Monday. Weekdays are numbered 1 through 7.
WeekNo1 = WEEKNUM('Calendar'[Date], 2)

WEEKDAY(<date>, <return_type>)
Returns a number from 1 to 7 identifying the day of the week of a date. By default the day
ranges from 1 (Sunday) to 7 (Saturday).
Note:
Return type: 1, week begins on Sunday (1) and ends on Saturday (7). numbered 1 through 7.
Return type: 2, week begins on Monday (1) and ends on Sunday (7).
Return type: 3, week begins on Monday (0) and ends on Sunday (6).numbered 0 through 6.

WeekdayNo = WEEKDAY('Calendar'[Date], 2)
WeekDay = SWITCH('Calendar'[WeekdayNo], 1, "Mon",
2, "Tue",
3, "Wed",
4, "Thu",
5, "Fri",
6, "Sat", "Sun"
)
TIME(hour, minute, second)
Converts hours, minutes, and seconds given as numbers to a time in datetime format
Time1=TIME(27,0,0)
Time2=TIME(3,0,0)
Note: To show time only, then change the data type from Date/Time to Time.

TIMEVALUE(time_text)
Converts a time in text format to a time in datetime format.
Time Value = TIMEVALUE("03:00:00 AM")

HOUR(<datetime>)
Returns the hour as a number from 0 (12:00 A.M.) to 23 (11:00 P.M.).
Task: Create a column to show current hour
Current Hour = HOUR(NOW())
MINUTE(<datetime>)
Returns the minute as a number from 0 to 59, given a date and time value.
Current Min = MINUTE(NOW())

SECOND(<time>) : Returns the seconds of a time value, as a number from 0 to 59.


Current Sec = SECOND(NOW())

EDATE(<start_date>, <months>)
Returns the date that is the indicated number of months before or after the start date.
EDate1 = EDATE("2020-01-29", 1)
EDate2 = EDATE("2020-01-29", -1)

EDate3= EDATE("2020-01-30", 1)
EDate4 = EDATE("2020-01-31", -1)

Note: all expressions will return next month end of the date if there is no specific day in the
next month(Feb)

EOMONTH(<start_date>, <months>)
Returns the date in datetime format of the last day of the month, before or after a specified
number of months.
EOMonth1 = EOMONTH("2020-01-10",0)
EOMonth2 = EOMONTH("2020-01-25",1)
EOMonth3 = EOMONTH("2020-01-02",1.5)
Note: If start_date is not a valid date, EOMONTH returns an error.

FORMAT: It is used to format the date and time based on predefined formats and custom
formats as well based on requirement.
The following are the predefined format specifications
i. "General Date"
ii. "Long Date" OR "Medium Date"
iii. "Short Date"
iv. "Long Time" OR "Medium Time"
v. "Short Time"

Task: Create a new columns to show Long Date, Short Date, Long Time and Short Time
Long Date = FORMAT('Calendar'[Date], "Long Date")
Short Date = FORMAT('Calendar'[Date], "Short Date")
Long Time = FORMAT(NOW(), "Long Time")
Short Time = FORMAT(NOW(), "Short Time")
The following are the custom format specifications
(/) --> Date Separator
(:) --> Time Separator
d----> Displays day number
dd--->Displays day in the form of (01--leading zero)
ddd---> Displays day in the form of "Mon"
dddd--> Displays day in the form of "Monday"

M--> Displays Month number


MM--> Displays Month number by leading zero
MMM--> Displays Month in the form of "Jan"
MMMM --> Displays Month in the form of "January"

y--> Displays Year number


yy--> Displays Year number by leading zero
yyy--> Displays Year in the form of four digits
yyyy --> Displays Year in the form of four digits

Task: Create a new column to show the date with the following format
"M/d/yyyy"

Custom Date1 = FORMAT('Calendar'[Date], "M/d/yyyy")


Custom Date2 = FORMAT('Calendar'[Date], "MM/dd/yyyy")
Custom Date3 = FORMAT('Calendar'[Date], "MMM/ddd/yyyy")
Custom Date4 = FORMAT('Calendar'[Date], "MMM-YY")
Custom Date5= FORMAT(DimDate[Date], "MMM dd, YYYY")
LOGICAL FUNCITONS
Logical functions act upon an expression to return information about the values or sets in
the expression.
The following are the list of logical Functions
1. AND
2. OR
3. TRUE
4. FALSE
5. NOT
6. IF
7. SWITCH
8. IFERROR

AND(<logical1>, <logical2>)
Checks whether both arguments are TRUE, and returns TRUE if both arguments are TRUE.
Otherwise returns FALSE.
AND = AND(10 > 9, -10 < -1)

CheckAnd=IF(AND(10 > 9, -10 < -1), "All true", "One or more false" )

Note: We can also use Logical AND (&&) operator directly in expression.
Logical AND = 10 > 9 && -10 < -1
IF&& = IF(10>9 && -10<-1, "All are true", "One of them is false")

Show the Employee names in lower case, if the employee is working as CLERK and who is
part of Department number 30 else show names in Upper case

Employee1 = IF(AND(Employee[JOB] = "CLERK", Employee[DEPTNO] = 30),


LOWER(Employee[ENAME]),
UPPER(Employee[ENAME])
)

Employee2 = IF(Employee[JOB] = "CLERK" && Employee[DEPTNO] = 30,


LOWER(Employee[ENAME]),
UPPER(Employee[ENAME])
)
OR(<logical1>,<logical2>)
Checks whether one of the arguments is TRUE to return TRUE. The function returns FALSE if
both arguments are FALSE
OR = OR(10 > 9, -10 < -1)
Checks=IF(OR(10 > 9, -10 < -1), "One or More True", "All are False" )
Show the Employee names in lower case, if the employee is working as CLERK or if the
employee is working in Department number 30 else show names in Upper case

Employee3 = IF(OR(Employee[JOB] = "CLERK", Employee[DEPTNO] = 30),


LOWER(Employee[ENAME]),
UPPER(Employee[ENAME])
)

Employee4 = IF(Employee[JOB] = "CLERK"|| Employee[DEPTNO] = 30,


LOWER(Employee[ENAME]),
UPPER(Employee[ENAME])
)

FALSE()
Returns the logical value FALSE.

TRUE()
Returns the logical value TRUE.
Create a new column to return FALSE, if the salary is less than 2000 else return TRUE

Boolean = IF(Employee[SAL]<2000, FALSE(), TRUE())

IF(logical_test>,<value_if_true>, value_if_false)
Checks if a condition provided as the first argument is met. Returns one value if the
condition is TRUE, and returns another value if the condition is FALSE.
Boolean = IF(EMP[SAL]<2000, FALSE(), TRUE())

Create a column display Eligible if the Employee is eligible for COMM else display Not
Eligible ?

Is Eligible = IF(ISBLANK(Employee[COMM]), "Not Eligible", "Eligible")

IFERROR(value, value_if_error)
Evaluates an expression and returns a specified value if the expression returns an error;
otherwise returns the value of the expression itself.
The following example returns 9999 if the expression 25/0 evaluates to an error. If the
expression returns a value other than error, that value is passed to the invoking expression.
=IFERROR(25/0,9999)
NOT(<logical>)
Changes FALSE to TRUE, or TRUE to FALSE.
NOT = NOT(AND(10>9, -10<-1))

SWITCH(<expression>, <value>, <result>[, <value>, <result>]…[, <else>])


Evaluates an expression against a list of values and returns one of multiple possible result
expressions

WeekDay = SWITCH(WEEKDAY('Calendar'[Date], 2), 1, "Mon",


2, "Tue",
3, "Wed",
4, "Thu",
5, "Fri",
6, "Sat", "Sun"
)

Difference between IF and SWITH ?


If function can take only one condition with all the operators(=,>,>=,<,<=, <>)
Switch function can take multiple conditions with all the operators(=,>,>=,<,<=, <>) but it
should not be a first expression. As First Expression, it will take only = by default

Note: To use other than equal operator, we need to write the following expressions

Task: Create a column to show Yes if the salary is less than 2000 else show No
If1 = IF(Employee[SAL]<2000, "Yes", "No")
Switch = SWITCH(TRUE(),
Employee[SAL]<2000, "Yes", "No"
)

Task: Create a new column with the following definition


If the employee salary is less than 1000 then show Red,
If the employee salary is greater than or equal to 1000 and less than 3000 then Gold
Else Green
Information Functions
IsBlank()
IsError()
IsNumber()
IsText()
IsEven()
UserName()
UserPrincipleName()

IsBlank() : Checks whether value is blank or not. If it is Yes, it returns TRUE else FALSE

Task: Create a new column to check whether the column to check Middle name is null or
not from DimCustomer table

IsBlank Middle Name = ISBLANK(DimCustomer[MiddleName])

Task: Create a new column to show "None" in place of blank if the column is having blank?
Replace Null =
IF(ISBLANK(DimCustomer[MiddleName]),
"None",
DimCustomer[MiddleName]
)
OR

Replace Null =
VAR vName = DimCustomer[MiddleName]
RETURN
IF(ISBLANK(vName),
"None",
vName
)

Task: Create a column, if the Commission is null give 100 else take as it is
New Comm = IF(ISBLANK(Employee[COMM]), 100, Employee[COMM])

Task: Create a new column get gross salary (Salary + Commission)

Gross Salary = EMP[SAL] + IF(ISBLANK(EMP[COMM]), 0, EMP[COMM])

Gross Saalary = Employee[SAL] + Employee[COMM] (From Jan Desktop, Blank is treating as


zero, when you apply addition)
IsError() : Checks whether value is error or not. If it is Yes, it returns TRUE else FALSE

Error = ISERROR(2/0)

IsError =
VAR a = 2
VAR b = 0
RETURN
ISERROR(a/b)

IsNumber() : Checks whether value is number or not. If it is Yes, it returns TRUE else FALSE
IsNumber = ISNUMBER(2)
IsNumber1 = ISNUMBER("2")

IsText() : Checks whether value is text or not. If it is Yes, it returns TRUE else FALSE

IsText =ISTEXT(2)
IsText1 = ISTEXT("2")

IsEven() : Checks whether value is even number or not. If it is Yes, it returns TRUE else FALSE
IsEven = ISEVEN(2)

UserName(): It is used to get the name of the user name with domain.

UserName = USERNAME()
Rudrasoft\bhaskar

Note: We can not create on table wise meaning record wise. We can only create at measure
level. This function will be used to provide security for the Data.

USERPRINCIPLENAME(): It is used to get the name of the user name without domain like
mailId's

UserPrinciplename= UserPrinciplename()

[email protected]

How can you get only User Alias except Domain ?


Measures:
Measures are known as Facts which are used to measure the business.
 It is not going to store the data as part of table. It stores only definition of the measure
in the Model.
 We can use the measure across various dimension tables. Same definition will give
different values based on context
 Measures are filter context whereas Columns are Row Context
 If you want to validate measures, then we need to use them in the reporting.
 We can also call measure from column from specific table

Aggregate Functions
AVERAGE: It is used to get average of the provided column values
AVERAGEA: It is also used to get average of the provided column values but it considers text
as zero, Boolean datatype False as zero, Boolean datatype True as 1 and space as null.
This function will work on Excel;
AVERAGEX: It is used to get average based on condition meaning conditional based average

COUNT: It is used to get count of the selected column values


COUNTA: It counts all types of the data
COUNTAX: It is used to count based on Condition
COUNTBLANK: It is used to get count of blanks only
COUNTROWS: It is used to get the count of rows of the table
COUNTX: It is used to get conditional based count

MAX: It is used to get maximum


MAXA: It is also used get maximum but consider all types
MAXX: It is used to get conditional based maximum

MIN: It is used to get minimum


MINA: It is also used get minimum but consider all types
MINX: It is used to get conditional based minimum

SUM: It is used to add all the values of a selected column. It will do operation in vertically.
SUMX: It is used to add the values of selected column based on condition(Expression). It will
do operation vertically and horizontally.
Task: Create a new column with the following DAX expressions
Saalary = SUM(Employee[SAL])

Note: If you create above column, value is not changing for each and every record. If you
use same definition in the Measures, then we can see different values across various
dimensions

Task: Create a new measure with following script


Total Salary = SUM(Employee[SAL])

Create the following measures


AvgSal = AVERAGE(Employee[SAL])
Sum = SUM(Employee[SAL])
Min = MIN(Employee[SAL])
Max = MAX(Employee[SAL])
Cnt = COUNT(Employee[EMPNO])
SumX1 = SUMX(Employee, Employee[SAL]+10)
SumX2 = SUMX(FILTER(Employee, Employee[JOB] = "ANALYST" || Employee[JOB] =
"CLERK"), Employee[SAL]+10)

FILTER: It is used to filter/restrict based on condition. This function cannot base be used as
single function in the DAX expression as New Column and New Measure but we can use it in
Table Calculations and DAX queries. Return type of Filter function is table
Task: Create a measure to show average for only Managers

Avg for Managers =


AVERAGEX(FILTER(Employee, Employee[JOB] = "MANAGER"),
Employee[SAL]
)

Related(): It is used to get the related value from the related table. Make sure there should
be relationship existed for both tables else we cannot use Related function.

Task: Create a new measure to show average for Sales and Accounting
Avg for Sales & Acc = AVERAGEX(
FILTER(Employee, RELATED(DEPT[DNAME]) = "SALES" || RELATED(DEPT[DNAME]) =
"ACCOUNTING"),
Employee[SAL]
)

Calculate() : It is used to create a measure on top of other measure(directly or indirectly)

Task: Modify above task with Calculate function

Department = RELATED(DEPT[DNAME])
Calc = CALCULATE([Average], Employee[Department] = "Sales" || Employee[Department] =
"ACCOUNTING")

OR

Calc = CALCULATE([Average], Department[DNAME] = "SALES" || Department[DNAME] =


"ACCOUNTING")

IN
Returns True if the scalar value shows up in at least one row of the input relation.

Task: modify above task with IN function


Calc = CALCULATE([Average],
Department[DNAME] IN {"Sales", "Accounting"}
)
Task: Create a new column to show employee names in lowercase, if they are working as
Clerk and Manager else show them in Uppercase

IN = IF(EMP[JOB] IN {"CLERK", "MANAGER"},


LOWER(EMP[ENAME]),
UPPER(EMP[ENAME])
)

RELATEDTABLE(<tableName>) : Returns related tables filtered so that it only includes


related rows. It returns table
Task: Create a new column to show Sales Amount in DimProductCategory table

Sales Amount = SUMX(RELATEDTABLE(FactSales), FactSales[SalesAmount])


Note: Related function will be used to get the values from related parent table to child
table where as RelatedTable function will be used to get the values from related child table
to parent table. You cannot use RelatedTable alone in New column or New Measure, we
have to use with some other DAX functions like SUMX, MINX, MAXX…

All(): It is used to clear filter on selected table or column


Task: Create a measure to show grand total always

GrandTotal = SUMX(
ALL(Employee),
Employee[SAL]
)
Note: All function is used to clear all the filters on Employee table

NetWorkDays = CALCULATE(COUNT(DimDate[Datekey]), FILTER(DimDate, DimDate[Is


Weekdays] = "Yes"))

NetWorkDays = CALCULATE(COUNT(DimDate[Datekey]),
FILTER(DimDate, WEEKDAY(DimDate[Datekey], 2) < 6)
)
TIME INTELLIGENCE FUNCTIONS
DATESBETWEEN(<dates>,<start_date>,<end_date>)
Returns a table that contains a column of dates that begins with the start_date and
continues until the end_date.

Note:
If start_date is a blank date value, then start_date will be the earliest value in the dates
column.
If end_date is a blank date value, then end_date will be the latest value in the dates column.

Note:
The DATESBETWEEN function is provided for working with custom date ranges. If you are
working with common date intervals such as months, quarters, and years, we recommend
that you use the appropriate function, such as DATESINPERIOD.

Task: Create a new column to show Sales Amount for Q3

Sales Amount Q3 =
CALCULATE(
[Sales Amount],
DATESBETWEEN(DimDate[Datekey], DATE(2009, 07, 01), DATE(2009, 09, 31))
)

Note: There is duplicated data. Why ?

After Creating Relationship


DATESINPERIOD(<dates>,<start_date>,<number_of_intervals>,<interval>)
Returns a table that contains a column of dates that begins with the start_date and
continues for the specified number_of_intervals.

Task: Create a new measure to get Sales Amount for these dates 2009,07,05 and 2009,07,04
Fact Sales for 2 Days Prior =
CALCULATE([Sales Amount],
DATESINPERIOD(DimDate[Datekey], DATE(2009, 07, 05), -2, DAY)
)
Task: Create a column to show measure(Salary) for the last 7 days by using current date

Loading data from Excel file after setting current month dates

Last 7 Days Salary :=CALCULATE(


[Total Salary],
DATESINPERIOD(EMP[HIREDATE], TODAY()-1, -7, DAY
))

Last 7 Days Salary Excluding Current Day:=CALCULATE(


[Total Salary],
DATESINPERIOD(EMP[HIREDATE], TODAY()-1, -7, DAY
))

DATESMTD(<dates>)
Returns a table that contains a column of the dates for the month to date, in the current
context

DATESQTD(<dates>)
Returns a table that contains a column of the dates for the quarter to date, in the current
context.

DATESYTD(<dates> [,<year_end_date>])
Returns a table that contains a column of the dates for the year to date, in the current
context.

MTD Total:= CALCULATE(SUM(FactInternetSales[SalesAmount]),


DATESMTD(DimDate[FullDateAlternateKey]))

MTD Total = CALCULATE([Sales Amount],


DATESMTD(DimDate[Datekey])
)

QTD Total = CALCULATE([Sales Amount],


DATESQTD(DimDate[Datekey])
)
YTD Total = CALCULATE([Sales Amount],
DATESYTD(DimDate[Datekey])
)
ENDOFMONTH(<dates>)
Returns the last date of the month in the current context for the specified column of dates.

ENDOFQUARTER(<dates>)
Returns the last date of the quarter in the current context for the specified column of dates.

ENDOFYEAR(<dates> [,<year_end_date>])
Returns the last date of the year in the current context for the specified column of dates.
Create the following columns to find the Sales for the end of month, end of quarter and end
of year
EndOfMonth Sales:= CALCULATE(
FactSales[Sales Amount],
ENDOFMONTH(DimDate[Datekey])
)

EndOfQuarter Sales:= CALCULATE(


FactSales[Sales Amount],
ENDOFQUARTER(DimDate[Datekey])
)

EndOfYear Sales:= CALCULATE(


FactSales[Sales Amount],
ENDOFYEAR(DimDate[Datekey], "30-06")
)
FIRSTDATE(<dates>)
Returns the first date in the current context for the specified column of dates

Create the following measure in Employee table


First Day:=FIRSTDATE(EMP[HIREDATE])

First Day Salary:= CALCULATE(


[Salary],
FIRSTDATE(EMP[HIREDATE])
)
LASTDATE(<dates>)
Returns the last date in the current context for the specified column of dates.

Create the following measure in Employee table


Last Day:=LASTDATE(EMP[HIREDATE])

Last Day Salary:= CALCULATE(


[Salary],
LASTDATE(EMP[HIREDATE])
)

FIRSTNONBLANK(<column>,<expression>)
Returns the first value in the column, column, filtered by the current context, where the
expression is not blank

Create a measure to show Sales Amount on Quarter1 and Quarter4 else show Total Cost for
other Quarters

Sales Amount / Total Cost:=


IF(
FIRSTNONBLANK(DimDate[Quarter],1) = "Q1" ||
FIRSTNONBLANK(DimDate[Quarter],1) = "Q4" , FactSales[Sales Amount],
[Total Cost])

Modify above script with Switch function

Sales/Total:= SWITCH(TRUE(),
FIRSTNONBLANK(DimDate[Quarter],1)="Q1" ||
FIRSTNONBLANK(DimDate[Quarter],1) = "Q4", [Sales Amount],
[Total Cost]
)
LASTNONBLANK(<column>,<expression>)
Returns the last value in the column, column, filtered by the current context, where the
expression is not blank.

Note:
A table containing a single column and single row with the computed first value

NEXTDAY(<dates>)

Returns a table that contains a column of all dates from the next day, based on the
first date specified in the dates column in the current context.

Task: Create a measure to show next day sales by using Sales Amount

Next Day Sales:= CALCULATE(


[Sales Amount],
NEXTDAY(DimDate[Datekey])
)

PREVIOUSDAY(<dates>)
Returns a table that contains a column of all dates representing the day that is
previous to the first date in the dates column, in the current context.

Task: Create a measure to show previous day sales by using Sales Amount
Previous Day Sales:= CALCULATE(
[Sales Amount],
PREVIOUSDAY(DimDate[Datekey])
)

Data Validation by using Excel


Values: Sales Amount, Next Day Sales, Previous Day Sales
Rows: DateKey
NEXTMONTH(<dates>)

Returns a table that contains a column of all dates from the next month, based on
the first date in the dates column in the current context.

Task: Create a measure to show next month sales by using Sales Amount
Next Month Sales:= CALCULATE(
[Sales Amount],
NEXTMONTH(DimDate[Datekey])
)

PREVIOUSMONTH(<dates>)

Returns a table that contains a column of all dates from the previous month, based
on the first date in the dates column, in the current context.

Task: Create a measure to show previous month sales by using Sales Amount
Previous Month Sales:= CALCULATE(
[Sales Amount],
PREVIOUSMONTH(DimDate[Datekey])
)

Data Validation by using Excel


Values: Sales Amount, Next Month Sales, Previous Month Sales
Rows: Month
Filter: Year -- 2009

NEXTQUARTER(<dates>)
Returns a table that contains a column of all dates in the next quarter, based on the
first date specified in the dates column, in the current context.

PREVIOUSQUARTER(<dates>)

Returns a table that contains a column of all dates from the previous quarter, based
on the first date in the dates column, in the current context.

NEXTYEAR(<dates>[,<year_end_date>])

Returns a table that contains a column of all dates in the next year, based on the first
date in the dates column, in the current context.
Task: Create a measure to show next year sales by using Sales Amount
Next Year Sales:= CALCULATE(
[Sales Amount],
NEXTYEAR(DimDate[Datekey], "31-12"
))
PREVIOUSYEAR(<dates>[,<year_end_date>])

Returns a table that contains a column of all dates in the previous year, based on the
first date in the dates column, in the current context.

Task: Create a measure to show previous year sales by using Sales Amount
Previous Year Sales:= CALCULATE(
[Sales Amount],
PREVIOUSYEAR(DimDate[Datekey], "31-12"
))

Data Validation by using Excel


Values: Sales Amount, Next Year Sales, Previous Year Sales
Rows: Year

Task: Create a measure to show the variance of Current Year and Previous Year

Variance:= [Sales Amount] - [Previous Year Sales]

Data Validation by using Excel


Values: Sales Amount, Previous Year Sales, Variance
Rows: BrandName
Filter: Year -->2009

Task: Create a measure to show the % variance of Current Year and Previous Year

%Variance:= DIVIDE(([Sales Amount] - [Previous Year Sales]),


[Previous Year Sales]
)

OR

%Variance:= DIVIDE([Variance],
[Previous Year Sales]
)
Data Validation by using Excel
Values: Sales Amount, Previous Year Sales, Variance, %Variance
Rows: BrandName
Filter: Year -->2009

Task: Based on user selection, we need to change the number with the following options
1. Ones
2. Thousands
3. Millions

If the user selected Thousand, then we should show numbers in Thousands, If the user
selected Millions, then we should show the number in Millions.
By default, we can show either Ones or Thousands or Millions but we have shown Ones

Create the following tables and feed the data into Database
DROP TABLE DimNumberFormatting

CREATE TABLE DimNumberFormatting(


Sno INT,
FormatType VARCHAR(20),
FormatbyNumber BIGINT
)

--Feeding Data into DimNumberFormatting


INSERT INTO DimNumberFormatting VALUES
(1, 'Ones',1),
(2, 'Thousands',
1000),
(3, 'Millions',
1000000)
SELECT * FROM DimNumberFormatting

Load the DimNumberFormatting table int SSAS Tabular Model or Power BI


ISFILTERED:
It is used to return True, When there are direct filters on the specified column

Sales Amount:= IF(


ISFILTERED(DimNumberFormatting[FormatType]),
DIVIDE(
SUM(FactSales[SalesAmount]),
SUM(DimNumberFormatting[FormatbyNumber])
),
SUM(FactSales[SalesAmount])
)
Task: We are having Employee and Department tables which are having common column to
join the two tables by using relationship but without creating relationship, Is there any
possibility to split the data across Department names which are there in Department table?

SAMEPERIODLASTYEAR(<Dates>):
It is used to return set of dates in the current selection from previous year.
Task: Create a measure to show SamePeriodLastYear by using Sales Amount

Same Period Last Year:= CALCULATE(


[Sales Amount],
SAMEPERIODLASTYEAR(DimDate[Datekey])
)

Data Validation by using Excel


Pivot Table1:
Values: Sales Amount, Same Period Last Year
Filter: Year -->2009

Pivot Table2:
Values: Sales Amount
Filter: Year -->2008
Task: I have a Fact table which contains OrderDate, ShipDate and DueDate and having
Calender table which contains Dates and parts of them. I wanted to see the data with the
following format
Calendar Year Order Sales Amount Ship Sales Amount Due Sales Amount

UserRelationShip(): It is used to make active relationship, if there is multiple relationships.


Power BI or SSAS Tabular Model will allow only one active relationship between two tables.
If you have multiple relationships between two tables one will be active and others will de-
active relationships.

Active Relationship

Inactive/de-active Relationship --------

1. Load the data from FactInternetSales, DimDate(Calender), DimPromotion tables


2. Create One Active Relationship between FactInternetSales and Calender for
OrderDateKey Column

Create the following Measures:


Order Sales Amount:= SUM(FactInternetSales[SalesAmount])
Ship Sales Amount:= CALCULATE(
SUM(FactInternetSales[SalesAmount]),
USERELATIONSHIP(FactInternetSales[ShipDateKey], 'Date'[DateKey])
)

Due Sales Amount:= CALCULATE(


SUM(FactInternetSales[SalesAmount]),
USERELATIONSHIP(FactInternetSales[DueDateKey], 'Date'[DateKey])
)

Data Validation by using Excel


Values: Order Sales Amount, Ship Sales Amount, Due Sales Amount
Rows: Year

You might also like