MDX - What BI Developers Need To Know
-
Upload
mark-ginnebaugh -
Category
Technology
-
view
17.869 -
download
5
description
Transcript of MDX - What BI Developers Need To Know
What All Microsoft BI Developers What All Microsoft BI Developers Need to Know About MDXNeed to Know About MDX
Speaker: Nathan Peterson
Solid Quality Mentors
Silicon Valley SQL Server User Group
January 19, 2009
Mark Ginnebaugh, User Group Leader, [email protected]
Nathan PetersonNathan Peterson
� Solid Quality Mentors
�Currently working on an Analysis Services project for the US Army
� Lead developer of a local cube generating utility called CubeSlice
What do all developers need to know about What do all developers need to know about MDX? MDX?
� You should be able to:
� Create and debug Calculated Members.
� Create and debug Named Sets.
What you need to know to accomplish this:� What you need to know to accomplish this:
� Understand MDX Concepts.
� Learn MDX Syntax.
� Learn some MDX functions.
� Learn some practical applications of MDX.
What Is MDX?What Is MDX?
� Multi-Dimensional eXpressions
� SQL is used for relational queries, while MDX is used for multidimensional queries.
� Calculated members allow you to incorporate � Calculated members allow you to incorporate multidimensional logic into your cube.
� Named sets allow you to pre-define dynamic groups of members to be displayed on columns or rows.
Sample calculated memberSample calculated member
with member measures.[Last Year Sales Amount]as(measures.[Sales Amount], measures.[Sales Amount], ParallelPeriod
([Date].[Calendar].[Calendar Year],1,[Date].[Calendar].CurrentMember)
)
Sample named setSample named set
with set [Top 5 Products]astopcounttopcount
([Product].[Product].Members,5,Measures.[Internet Sales Amount])
Comparing MDX to SQLComparing MDX to SQL
� From
� SQL selects from a table.
�MDX selects from a cube.
� Dimensionality � Dimensionality
� SQL returns one or more columns and 0 or more rows.
�MDX can return data for 0, 1, 2, 3 or more axes.
� Where
� SQL has a filter.
�MDX has a slicer.
MDX query with two axes and two slicersMDX query with two axes and two slicers
select Measures.AllMembers on columns,[Date].[Calendar].&[2003].Children on rowsfrom [Adventure Works]from [Adventure Works]where ([Customer].[Customer Geography].[France],[Product].[Product Categories].[Bikes])
Dimensions and MeasuresDimensions and Measures
Same query, using axis numbers instead of axis Same query, using axis numbers instead of axis namesnames
select Measures.AllMembers on 0,[Date].[Calendar].&[2003].Children on 1from [Adventure Works]from [Adventure Works]where ([Customer].[Customer Geography].[France],[Product].[Product Categories].[Bikes])
Using MDX requires multidimensional thinkingUsing MDX requires multidimensional thinking
� In a cube
� Dimensions have hierarchies
� Hierarchies have levels
� Levels have members� Levels have members
� In a cellset
� Each axis contains a set
� Each set consists of a group of members or a group of tuples
� Tuples have members from different hierarchies
Multidimensional thinking Multidimensional thinking –– Where are you?Where are you?
� Every member is in a level.
� Every level is in a hierarchy.
� Every hierarchy is a part of a dimension.
� For every cell of the cellset, there’s (almost) always a Current Member for each hierarchy.
� The Current Member may be set from the column, the row, the slicer, or the default member.
Create a set by listing membersCreate a set by listing members
� The simplest set is a list of members.
� The boundaries of the set are indicated with curly braces {}.
selectselect{[Product].[Category].[All Products],[Product].[Category].[Accessories],[Product].[Category].[Bikes],[Product].[Category].[Clothing],[Product].[Category].[Components]} on 0from [Adventure Works]
Create a set with a functionCreate a set with a function
� There are many MDX functions that create sets.
� This query uses the .Members function to return all the members from a hierarchy – and gives the same result as the previous query.result as the previous query.
� You don’t have to use {} when you create a set with a function.
select [Product].[Category].Members on 0from [Adventure Works]
TuplesTuples
� Each cell in a cellset shows data for one particular member from each hierarchy.
� A tuple is a way of specifying which member should be used from each of the hierarchies.be used from each of the hierarchies.
� Tuples are written like points in a geometric grid:
� (6,3) identifies point 6 on the x-axis and point 3 on the y-axis.
� ([2009],[US],[Bikes],[Internet Sales Amount]) identifies Internet Sales for Bikes in the US in 2009.
2 Dimensional 2 Dimensional TupleTuple
6
5
4
3
2 Dimensional Tuple
1 2 3 4 5 6 7 8
3
2
1
(6, 2)
Create a set by listing tuplesCreate a set by listing tuples
select{([Date].[Calendar Year].&[2002],[Product].[Category].[Accessories]),(
[Date].[Calendar Year].&[2002],[Date].[Calendar Year].&[2002],[Product].[Category].[Bikes]),(
[Date].[Calendar Year].&[2003],[Product].[Category].[Accessories]),(
[Date].[Calendar Year].&[2003],[Product].[Category].[Bikes])
}
on 0from [Adventure Works]
Listing Listing TuplesTuples
([2006], [Mountain Bikes])
2 Dimensional Tuple
[Accessories]
[Clothing]
[Touring Bikes]
[Road Bikes]
1 2 3 4 5 6 7 8
([2006], [Mountain Bikes])
2 2 2 2 2 2 2 20 0 0 0 0 0 0 00 0 0 0 0 0 0 0
[Road Bikes]
[Mountain Bikes]
[All Products]
Create a set of tuples by multiplying two sets of Create a set of tuples by multiplying two sets of membersmembers
select {
[Date].[Calendar Year].&[2002],[Date].[Calendar Year].&[2003]
}}*{
[Product].[Category].[Accessories],[Product].[Category].[Bikes]
}on 0from [Adventure Works]
3 Dimensional 3 Dimensional TupleTuple
[Accessories]
[Clothing]
[Touring Bikes]
[Road Bikes]([2006], [Mountain Bikes], [Red])
3 Dimensional Tuple Difficult to Show in 3 Axes –Where to place the point?
1 2 3 4 5 6 7 8
[Road Bikes]
[Mountain Bikes]
[All Products]
([2006], [Mountain Bikes], [Red])
2 2 2 2 2 2 2 20 0 0 0 0 0 0 00 0 0 0 0 0 0 0
[Red][Blue]
[Pink]
3 Dimensional 3 Dimensional TupleTupleCombining 2 Hierarchies on 1 AxisCombining 2 Hierarchies on 1 Axis
([Blue], [Road Bikes])
([Red], [Road Bikes])
([Blue], [Mountain Bikes])
([Red], [Mountain Bikes])
3 Dimensional Tuple
1 2 3 4 5 6 7 8
([Red], [Mountain Bikes])
([Blue], [All Products])
([Red], [All Products])([2006], [Mountain Bikes], [Red])
2 2 2 2 2 2 2 20 0 0 0 0 0 0 00 0 0 0 0 0 0 0
The Where clauseThe Where clause
� The Where clause is an optional part of an MDX query.
� The Where clause is a slicer, not a filter.
� You can’t use the Where clause for limiting the value to � You can’t use the Where clause for limiting the value to a threshold (Sales over $10,000).
� Use the Filter function for filtering.
� The Where clause often looks like a tuple and actually is a tuple – but it doesn’t have to be.
Where clause using a tuple Where clause using a tuple –– one member from one member from each referenced hierarchyeach referenced hierarchy
select Measures.[Internet Sales Amount] on 0from [Adventure Works]from [Adventure Works]where ([Customer].[Customer Geography].[France],[Product].[Product Categories].[Bikes])
Where clause with slicing on multiple members Where clause with slicing on multiple members from one hierarchyfrom one hierarchy
select Measures.[Internet Sales Amount] on 0from [Adventure Works]where where ([Customer].[Customer Geography].[France],
{[Product].[Product Categories].[Bikes],[Product].[Product Categories].[Clothing]}
)
The With clauseThe With clause
� The With clause is used for creating both calculated members and named sets.
� These calculated members and named sets are only valid for the life of the query.valid for the life of the query.
� You can also create calculated members and named sets that are persistent:
� Lasting for the life of a session.
� Created permanently in the cube.
Creating calculated member in the With clauseCreating calculated member in the With clause
with member Measures.[Average Internet Sales]as[Measures].[Internet Sales Amount][Measures].[Internet Sales Amount]/[Measures].[Internet Order Count],format_string = "currency"select {Measures.[Average Internet Sales]} on 0from [Adventure Works]
Members, Sets, Members, Sets, TuplesTuples
Set of
(Partial)
([Blue], [Road Bikes])
([Red], [Road Bikes])
([Blue], [Mountain Bikes])
([Red], [Mountain Bikes])
Members, Sets, Tuples
Member
Set of Members
(Partial)
Tuples
1 2 3 4 5 6 7 8
([Red], [Mountain Bikes])
([Blue], [All Products])
([Red], [All Products])([2006], [Mountain Bikes], [Red])
(Partial) Tuple
2 2 2 2 2 2 2 20 0 0 0 0 0 0 00 0 0 0 0 0 0 0
Creating named set in the With clauseCreating named set in the With clause
with set [Products - High Selling on Internet]asfilter
(([Product].[Product].[Product].Members,[Measures].[Internet Sales Amount]
> 50000)
select {Measures.[Internet Sales Amount]} on 0,[Products - High Selling on Internet] on 1from [Adventure Works]
Full Full TupleTuple
([Blue], [Road Bikes])
([Red], [Road Bikes])
([Blue], [Mountain Bikes])
([2006], [Mountain Bikes], [Red], [All
Promotions], [All Gender],
[Measures].[Reseller Sales Amount],
etc…)
1 2 3 4 5 6 7 8
([Red], [Mountain Bikes])
([Blue], [All Products])
([Red], [All Products])
etc…)
2 2 2 2 2 2 2 20 0 0 0 0 0 0 00 0 0 0 0 0 0 0
MDX PunctuationMDX Punctuation
� Use {} for sets.
� Use () for tuples.
� Use [] for names of cubes, dimensions, hierarchies, � Use [] for names of cubes, dimensions, hierarchies, levels, and members.
� Use commas all over the place (except not between multiple calculated members or named sets defined in the same query).
Where to write your MDXWhere to write your MDX
� In a client application like PerformancePoint, which allows you to write code for calculated measures and sets.
In a query editor like the SQL Server Management � In a query editor like the SQL Server Management Studio.
� In the MDX Script of a cube.
TIP: It’s often easier to write the code in a query editor first and then put it into the MDX Script.
Writing MDX for a KPIWriting MDX for a KPI
� You can write MDX to create the values for a KPI, whether you’re working with Analysis Services KPIs or PerformancePoint Services KPIs.
For both tools, it’s easier to create calculated � For both tools, it’s easier to create calculated members in the MDX script for the values first.
� TIP: When building KPIs in the BIDS, use a template for assigning the Status and the Trend.
Functions Functions –– Navigating within a levelNavigating within a level
� PrevMember
� NextMember
� Lag()� Lag()
� Lead()
Examples of navigating in a levelExamples of navigating in a level
� Navigation functions are often used with Dates.
� Note: PrevMember, Lag(1), and Lead(-1) all return the same member.
[1997].PrevMember[1997].PrevMember[1996]
[March 2010].NextMember [April 2010][10 April 2009].Lag(2) [8 April 2009][December 2009].Lead(12) [December 2010]
Functions Functions –– All in the FamilyAll in the Family
� Parent
� Children, FirstChild, LastChild
� DescendantsDescendants
� Ancestor, Ascendants
� Siblings, FirstSibling, LastSibling
� Cousin
Examples of family functionsExamples of family functions
� Some of the family functions return individual members, while other return sets.
� If a function returns an individual member, you can use another function with it.
[Mar 1997].Parent [1997][Q1 2009].Children [Jan 09]:[Mar 09][2009].FirstChild [Q1 2009]Descendants([2009], 2) [Jan 09]:[Dec 09]Descendants([2009],[Date])[1Jan09]:[31Dec09]Ancestor([Mar 2008], 3) [2008]FirstSibling([Mar 2007]) [Jan 2007]
Functions Functions –– Multiplying, adding, subtracting, Multiplying, adding, subtracting, intersecting setsintersecting sets
� Set multiplication, addition, and subtractions can be indicated with mathematical symbols or with functions.
Multiplication * Crossjoin
Addition + Union
Subtraction - Except
Intersection Intersect
Example of set multiplicationExample of set multiplication
� These two sets are equivalent.
[Date].[Fiscal].[Month].members* [Product].[Product].members[Product].[Product].members
Crossjoin([Date].[Fiscal].[Month].members,[Product].[Product].members)
Practical Applications of MDXPractical Applications of MDX
� Comparing with a previous time period.
� Comparing with the same time period in the previous year.
� Year-To-Date.
� Rolling Average.
� Percent contribution.
Comparing with a previous time periodComparing with a previous time period
with member Measures.[Last Month Sales]as(Measures.[Internet Sales Amount],[Date].[Calendar].PrevMember[Date].[Calendar].PrevMember)select{Measures.[Internet Sales Amount],Measures.[Last Month Sales]} on 0,[Date].[Calendar].[Month].members on 1from [Adventure Works]
Comparing with the same period in the previous Comparing with the same period in the previous yearyear
with member measures.[Last Year Sales Amount]as(measures.[Sales Amount], measures.[Sales Amount], ParallelPeriod
([Date].[Calendar].[Calendar Year],1,[Date].[Calendar].CurrentMember)
)
YearYear--ToTo--Date Date
with member measures.[YTD Sales]assum(ytd([Date].[Calendar].CurrentMember),ytd([Date].[Calendar].CurrentMember),Measures.[Internet Sales Amount])
select{Measures.[Internet Sales Amount],Measures.[YTD Sales]} on 0,[Date].[Calendar].[Month].members on 1from [Adventure Works]
Rolling AverageRolling Average
With member measures.[Previous 6 Month Rolling AVG]assum([Date].[Calendar].lag(6):[Date].[Calendar].lag(6):[Date].[Calendar].lag(1),
Measures.[Internet Sales Amount]) / 6
select{Measures.[Internet Sales Amount],Measures.[Previous 6 Month Rolling AVG]} on 0,[Date].[Calendar].[Month].members on 1from [Adventure Works]
Percent ContributionPercent Contribution
With member Measures.[Percent of Parent Sales]asMeasures.[Internet Sales Amount]/(Measures.[Internet Sales Amount],Measures.[Internet Sales Amount],[Product].[Product Categories].Parent)
select{Measures.[Internet Sales Amount],Measures.[Percent of Parent Sales]} on 0,[Product].[Product Categories]. members on 1from [Adventure Works]
Additional topics Additional topics –– if there’s timeif there’s time
� Dealing with exceptions
� String manipulation
� GenerateGenerate
� Recursion
Dealing with exceptionsDealing with exceptions
� A calculation needs to be valid everywherewith member [Measures].[% Change # of Customers]ascasewhen [Date].[Fiscal].CurrentMember.Level.Ordinal = 0 then "NA” when [Date].[Fiscal].CurrentMember.Level.Ordinal = 5 then Null when [Date].[Fiscal].CurrentMember.Level.Ordinal = 5 then Null when isempty
( ([Date].[Fiscal].CurrentMember.PrevMember, [Measures].[Customer Count])) then null
else( ([Date].[Fiscal].CurrentMember, [Measures].[Customer Count])-([Date].[Fiscal].PrevMember, [Measures].[Customer Count])) /([Date].[Fiscal].PrevMember,[Measures].[Customer Count])end
Functions Functions -- String manipulationString manipulation
� Turning the current date into a member reference
Strtomember((
"[Date].[Fiscal].[Date].&["+ cstr(year(now()) - 6)+ right("0" + cstr(month(now())), 2)+ right("0" + cstr(day(now())), 2)+ "]"
)
The Generate functionThe Generate function
� What are the five top products most purchased by people living in my top five cities?
generate(topcounttopcount([Customer].[Customer Geography].[City].members,5,[Measures].[Internet Sales Amount] ),
crossjoin([Customer].[Customer Geography].CurrentMember,topcount([Product].[Product].[Product].members,5,[Measures].[Internet Sales Amount]
) ) )
RecursionRecursion
� Finding the most recent purchase
with member measures.[Most Recent Purchase]member measures.[Most Recent Purchase]asiif
([Measures].[Internet Sales Amount] > 0,[Measures].[Internet Sales Amount],[Date].[Calendar].PrevMember)
Thank youThank you
� http://www.databasejournal.com/article.php/1459531/
� http://msdn.microsoft.com/en-us/library/ms145970.aspx
� http://www.sqlserveranalysisservices.com
� http://www.ssas-info.com/analysis-services-faq/27-mdx
� http://www.mosha.com/msolap/mdx.htm
� http://cwebbbi.spaces.live.com
To learn more or inquire about speaking opportunities, please contact:
Mark Ginnebaugh, User Group Leader