olap and mdx - day 1
DESCRIPTION
Olap and MdxTRANSCRIPT
MSAS MDX
Presenter NameTitle
MDX Syntax
MDX Syntax
Specifying a Measure
If you wish to define rows and columns that are not measures themselves then a measure can be selected via the WHERE clause to specify context.
SELECT
{[Time].[1997],[Time].[1998]} on rows,
{[Store].[All Stores].[USA]} on columns
FROM Warehouse
WHERE [Measures].[Warehouse Sales]
MDX Syntax
The SELECT clause defines the contents of the axes.
The FROM clause defines the connection to the cube or OLAP source.
The WHERE clause defines the slicer or context based on members and member sets.
MDX results are a smaller multi-dimensional cube derived from the original cube source. SQL results are columnar and only ever define a single axis.
WITH MEMBER
“WITH MEMBER” can be used to create calculated members.
Example:
WITH MEMBER dimension.name AS 'Expression'
dimension is the target dimension to contain the new calculated member.
name is the alias for the result of the new expression
Expression is the calculation that is required to define the new calculated member.
WITH MEMBER
WITH
MEMBER [Measures].[Margin] AS
'[Measures].[Warehouse Sales]-[Measures].[Warehouse Cost]'
SELECT
{([Time].[1998].children)} ON COLUMNS,
{([Warehouse].[Country].members)} ON ROWS
FROM Warehouse
WHERE ([Measures].[Margin])
Commenting MDX
Comments can written in MSAS MDX using
//
--
/*…*/
“//” and “--” can be placed on lines of existing code. The rest of the line will be interperted as a comment. This applies to a single line only.
“/* … */” (ellipsis replaces comment text) can be used within existing code. Any text between “/*” and “*/” will be treated as a comment. This can be used across multiple lines of code.
Set Syntax
“{ … }” defines a set of members
Example: {[Time].[1997],[Time].[1998]}
The set of two members (1997 and 1998) from the Time Dimension.
The result is really a set of tuples where each tuple is defined by the intersection of the listed members and the default measure for the cube.
Q4
Time
Q1 Q2 Q32005
Sales Territory
CA
OR
WA
OLAP Cubes - What’s a “tuple”?
Pro
du
ct
Camping
Mountaineering
Outdoor Protection
Golf
Personal Equip.
Tuple – is a combination of members from one or more dimensions. In this case we have:
tuple([Q4], [Golf], [WA])
All other dimension members are implied.
The value returned would be the default measure i.e. [unit sales]
C8 Report Studio Speak- It’s still a tuple
tuple( currentMember([goc].[Products].[Products] ),
[Quantity sold] , [2006 Q 4] )
= 1,222
Defining a Tuple
Parentheses are used to define a tupleSELECT
{[Time].[1997],[Time].[1998]} on rows,
{[Store].[All Stores].[USA]} on columns
FROM Warehouse
WHERE ([Measures].[Warehouse Sales],[Store Type].[All Store Type].[Deluxe Supermarket])
Tuples on edges
A tuple defined for an axis (edge) will result in nested members
SELECT
{[Product].[All Products].[Drink].[Alcoholic Beverages]} on rows,
{([Store].[All Stores].[USA],[Time].[1997])} on columns
FROM Warehouse
WHERE ([Measures].[Warehouse Sales])
Specifying Ranges
The “:” can be used to leverage the natural order of members within a level
SELECT
{ [Measures].[Store Invoice]: [Measures].[Warehouse Profit]} ON COLUMNS,
{ [Time].[1997], [Time].[1998] } ON ROWS
FROM Warehouse
WHERE
([Warehouse].[All Warehouses].[USA].[CA])
NON EMPTY
The “NON EMPTY” clause can be used to eliminate tuples that do not have defined measure values.
SELECT
{ [Measures].[Units Shipped], [Measures].[Units Ordered] } ON COLUMNS,
[Store].Members ON ROWS
FROM [Warehouse]
NON EMPTY
The “NON EMPTY” clause can be used to eliminate tuples that do not have defined measure values.
SELECT
{ [Measures].[Units Shipped], [Measures].[Units Ordered] } ON COLUMNS,
NON EMPTY [Store].Members ON ROWS
FROM [Warehouse]
Methods and Functions
MSAS mixes two forms, Method and Function calls.
Methods
[Time].[Year].membersSELECT { [Time].[Year].members } ON ROWS, {[Measures].[Warehouse Cost]} on
COLUMNSFROM Warehouse
Functions
Ancestor( [Time].[1997].[Q1], [Time].[Year] )SELECT {Ancestor( [Time].[1997].[Q1], [Time].
[Year] )} ON ROWS, {[Measures].[Warehouse Cost]} on
COLUMNSFROM Warehouse
Methods
.Parent
.Children
.FirstChild
.LastChild
.FirstSibling
.LastSibling
.Members
.CurrentMember
.PrevMember
.NextMember
.Item()
(Others exist)
Dimensions, MDX & The Family Tree- Navigating a dimension using MDX
Jan Feb Mar
Q1 Q2 Q3
Oct Nov Dec
Q4
2005
Q1 Q2 Q3 Q4
2006
All
Parent of [Q1 2005] FirstChild
of [2005]FirstSibling of [Q4 2006]
FirstSibling of [Q1 2006]
NextMember of [Nov 2005]
PrevMember of [Nov 2005]
Cousin ([Jan 2005], [Q4])
Sets of data in MDX- Collecting data to use as a group using MDX
Jan Feb Mar
Q1 Q2 Q3
Oct Nov Dec
Q4
2005
Q1 Q2 Q3 Q4
2006
All
Children of [2006]
PeriodsToDate ([Year], [Q3 2005])
Members( [Months] )
Tail(members([Quarters], 2)
Head(members([Months], 2)
Parent
Returns the member directly above the specified member in the same hierarchy
SELECT
{[Time].[Year].members} ON COLUMNS,
{[Booker].Parent} ON ROWS
FROM [Warehouse]
WHERE ([Measures].[Units Shipped])
.Children
The members directly below the specified member of the hierarchy
SELECT
{[Store].[All Stores].[Canada]} ON COLUMNS,
{[Time].[Year].[1998].children} ON ROWS
FROM [Warehouse]
WHERE ([Measures].[Units Shipped])
Workshop
.Parent – Which city is [Bellmont Distributing] in? What is the parent of [Dairy]?
.Children – What types of Drinks are sold?
.FirstChild – What is the first month available in the Time dimension?
.LastChild – What is the last month available in the Time dimension?
.FirstSibling – What is the first State/Province relative to [Warehouse].[Veracruz] from the same country?
.LastSibling – What is the last State/Province relative to [Warehouse].[Veracruz] from the same country?
.Members – Make a list of all the Store Cities.
– Make a list of all Years, Quarters, and Months.
.NextMember – Which year follows 1997?
.PrevMember – What is the previous measure from [Store Invoice]?
CurrentMember
Allows processing of an expression relative to the current position within the members on an axis (dimension)
WITH MEMBER [Measures].[Percent of Base] AS '([Warehouse].currentMember,[Measures].[Warehouse
Sales])/([Warehouse].[All Warehouses],[Measures].[Warehouse Sales])'
SELECT {([Time].[1998])} ON COLUMNS, {([Warehouse].[Country].members)} ON ROWSFROM WarehouseWHERE ([Measures].[Percent of Base])
CurrentMember Workshop
Calculate the Year over Year variance in Warehouse Sales for each Country. i.e. difference of the current Year from the prior Year.
WITH
MEMBER [Measures].[YOY Variance] AS
‘Expression'
SELECT
{([Time].[Year].members)} ON COLUMNS,
{([Warehouse].[Country].members)} ON ROWS
FROM Warehouse
WHERE ([Measures].[YOY Variance])
Item (tuple version)
«Tuple».Item(«Numeric Expression»)
Returns the member at the zero-based index defined by «Numeric Expression».
SELECT
{[Warehouse].[All Warehouses].[Canada]} on ROWS,
{([Time].[1998],[Store Type].[All Store Type].[Deluxe Supermarket]).item(1)} on COLUMNS
FROM [Warehouse]
WHERE [Measures].[Units Shipped]
Item (set version)
«Set».Item(«String Expression»[, «String Expression»...] | «Index»)
Returns a tuple specified by the «String Expression» of the function arguments.
«String Expression» can either define a complete tuple expression or a series of individual members for each dimension used (in order) by the set.
SELECT {[Warehouse].[All Warehouses].[Canada]} on COLUMNS, {CrossJoin([Time].[Quarter].Members, [Product].[Product Family].Members).Item("[1998].[Q1]","Food")} on
ROWSFROM [Warehouse]WHERE [Measures].[Units Shipped]
OR
SELECT {[Warehouse].[All Warehouses].[Canada]} on COLUMNS, {CrossJoin([Time].[Quarter].Members, [Product].[Product Family].Members).Item(“([1998].[Q1],Food)")} on
ROWSFROM [Warehouse]WHERE [Measures].[Units Shipped]
Functions (a small subset)
Ancestor()
Cousin()
ParallelPeriod()
PeriodsToDate()
LastPeriods()
Sum()
Order()
Union()
Filter()
CrossJoin()
Subset()
Generate()
TopCount()
Ancestor
Ancestor(«Member», «Distance»)
Ancestor(«Member», «Level»)
Returns the member at the level or distance specified relative to the specified «Member».
SELECT {[Warehouse].[All Warehouses].[Canada]} on COLUMNS, {Ancestor([Time].[1998].[Q2].[5], 2)} on ROWSFROM [Warehouse]WHERE [Measures].[Units Shipped]
OR
SELECT {[Warehouse].[All Warehouses].[Canada]} on COLUMNS, {Ancestor([Time].[1998].[Q2].[5], [Time].[Year])} on ROWSFROM [Warehouse]WHERE [Measures].[Units Shipped]
Cousin
Cousin(«Member1», «Member2»)
Find the member in the same relative position as «Member1» given a new parent member, «Member2».
SELECT
{Cousin([Time].[1997].[Q1],[Time].[1998])} ON COLUMNS
FROM [Warehouse]
ParallelPeriod
ParallelPeriod([«Level»[, «Numeric Expression»[, «Member»] ] ])
Similar to Cousin
Returns a member in the same relative position as «Member» but with an ancestor at «Level» that is «Numeric Expression» away from the ancestor of «Member».
SELECT {[Warehouse].[All Warehouses].[Canada]} on COLUMNS, {ParallelPeriod([Time].[Year], 1, [Time].[1998].[Q2].[5])} on ROWSFROM [Warehouse]WHERE [Measures].[Units Shipped]
PeriodsToDate
PeriodsToDate([«Level»[, «Member»] ])
Returns all the members from the start of «Level» up to and including «Member»
SELECT
{[Warehouse].[All Warehouses].[Canada]} on COLUMNS,
{PeriodsToDate([Time].[Year], [Time].[1998].[Q2].[5])} on ROWS
FROM [Warehouse]
WHERE [Measures].[Units Shipped]
LastPeriods
LastPeriods(«Index»[, «Member»])
Returns a number of members, specified by «Index» and from the same level as «Member», up to and including «Member».
SELECT {[Warehouse].[All Warehouses].[Canada]} on COLUMNS, {LastPeriods(3, [Time].[1998].[Q2].[5])} on ROWSFROM [Warehouse]WHERE [Measures].[Units Shipped]
Sum
Sum(«Set»[, «Numeric Expression»])
Aggregates the numeric values from «Numeric Expression» which are returned for each of the members of «Set».
WITH MEMBER [Measures].[ToDate] AS 'SUM(PeriodsToDate([Time].[Year],[Time].[1998].[Q3].[7]),[Measures].[Warehouse Sales])'
SELECT {[Measures].[ToDate]} ON COLUMNS, {[Store].[Store Country].members} ON ROWSFROM [Warehouse]
SUM Workshop
Fill in the expressions to populate Year to Date
Prior Year to Date
Rolling average of the Last 6 Months
WITH MEMBER [Measures].[YTD] AS '[Measures].[Units Shipped]' MEMBER [Measures].[Prior YTD] AS '[Measures].[Units Shipped]'
MEMBER [Measures].[Last 6 Months - SUM] AS '[Measures].[Units Shipped]'
SELECT { [Time].[Month].Members} ON ROWS, { [Measures].[Units Shipped],[Measures].[YTD], [Measures].[Prior YTD],
[Measures].[Last 6 Months - SUM]} ON COLUMNSFROM Warehouse
Order
Order(«Set», {«String Expression» | «Numeric Expression»}[, ASC | DESC | BASC | BDESC])
Sorts the set of members from «Set»
ASC and DESC respect the order of the hierarchy and sorts within this structure.
BASC and BDESC will “Break” the hierarchy and sort by the expression only.
SELECT {[Measures].[Units Shipped]} ON COLUMNS, { ORDER({[Store].[Store Country].Members, [Store].[Store State].members},
([Measures].[Units Shipped]) , DESC)} ON ROWSFROM [Warehouse]WHERE [Time].[1998]
Union
Union(«Set1», «Set2»[, ALL])
Combines two individual sets to return one set as a result
Alternate syntax 1 (Union): {«Set1» + «Set2»}
Alternate syntax 2 (Union All): {«Set1» , «Set2»}SELECT {[Measures].[Units Shipped]} ON COLUMNS, UNION([Store].[Store Country].Members, [Store].[Store
State].members) ON ROWSFROM [Warehouse]WHERE [Time].[1998]
Filter
Filter(«Set», «Search Condition»)
Returns the members of «Set» for which the «Search Condition» is true.
SELECT {[Measures].[Units Shipped]} ON COLUMNS, FILTER([Store].[Store State].members,[Measures].[Units
Shipped]>0) ON ROWSFROM [Warehouse]WHERE [Time].[1998]
SELECT {[Measures].[Units Shipped]} ON COLUMNS, FILTER([Store].[Store State].members,[Measures].[Units
Shipped]>25000) ON ROWSFROM [Warehouse]WHERE [Time].[1998]
Crossjoin
Crossjoin(«Set1», «Set2»)
Returns a set of tuples defined by the matching of all members in «Set1» to all the members in «Set2»
NON EMPTY can be used to eliminate empty intersections. Alternately, NonEmptyCrossJoin() can be used.
SELECT { CROSSJOIN([Store].[Store Country].members,[Time].
[Year].Members)} ON ROWS, { [Measures].[Units Shipped]} ON COLUMNSFROM Warehouse
TopCount
TopCount(«Set», «Count»[, «Numeric Expression»])
Returns the first «Count» members from «Set» after sorting them in descending order based on «Numeric Expression».
SELECT
{ TopCount([Store].[Store City].members,10,[Measures].[Units Shipped])} ON ROWS,
{ [Measures].[Units Shipped]} ON COLUMNS
FROM Warehouse
Generate
Generate(«Set1», «Set2»[, ALL])
Generate(«Set1», «String Expression»[, «Delimiter»])
Evaluates «Set2» or the «String Expression» for each member of «Set1».
SELECT { GENERATE([Product].[Product
Family].members,TopCount(Descendants([Product].currentMember,[Product].[Product Name]),2,[Measures].[Units Shipped]))} ON ROWS,
{ [Measures].[Units Shipped]} ON COLUMNSFROM Warehouse