SQLServerCentral Article

Introduction to MDX

,

This article is intended to get you started on Multi-Dimensional eXpressions,

the Microsoft OLAP query language. MDX allows you to do complex reports quickly

on Very Large Databases. We have reports that run on many millions of records

with over 20 fields in under a second! OLAP is a powerful technology.

OLAP is a way of looking at data that has been totaled up, but allowing any

report on that data you require. 

Suppose you were logging sales in SQL server, you could have a table [sales] which had [value], [customer], [product], [timeofsale], [salesrep], [store], [county] etc.  If you wanted to know how many sales each sales rep had made you might use:
select s.[salesrep], count (*) as 'total' from [sales] s group by s.[salesrep] 

If you had a lot of sales this report would take a long time.  Suppose you

wanted to report on something else at the same time?  You might want to

see a cross-tab report of [salesrep] by [product].  This is messy to

write in SQL as you have to use case statements for each value of whichever

field you want on the columns.

What we may need to do is build all these totals at a time of low load and then

make them easily accessible for reporting all the time.  This is what

analysis services does. In OLAP we would build a cube of this [sales] table.  We call them cubes

because they can be visualized as such for simpler reports.  As a cube can

have up to 128 dimensions however this metaphor quickly breaks down. 

Supposing that we only want to report on 3 fields ([timeofsale], [salesrep] and

[product]); we could think of all the reports you could want on those fields as

a cube. Each edge of the cube would have all the values of a field along it,

and each face would be a cross tab of two of the fields.

An introduction to the rest of the terminology may be useful at this point:

Dimension
A dimension is one of the fields that you want to report on. Dimensions have a

tree structure, allowing complicated data to be reported on at different

levels. For instance [timeofsale] could be a dimension if you wanted to report

on it

Measure
What we are actually reporting on, be it sum, count or average.
Level
A level is a step along a dimension. In [timeofsale] we could have [Year],

[Month], [Day] and [Hour] allowing us to report on sales per hour or products

year on year.

Member
A member is a value of a level. In [timeofsale].[Year] we might have [2001],

[2002], [2003], or in [timeofsale].[Month] we have [March], [April], [May] etc

Axis
This is what you set to put [product] across the columns, [timeofsale] down the

rows or report on a [salesrep] to a page. An MDX statement can have up to 128

axis, although it is rare to use more than 2. The first 5 have names:

0 Columns

1 Rows

2 Pages

3 Chapters

4 Sections

Dimensionality
This is an attribute of a collection of members or levels which describes what

dimensions they are from and what order those dimensions are in.

Tuple
A tuple is a collection of members which all have different dimensionality

(so each is from a different dimension). Tuples have () brackets around them,

but don't need them when there is only one member. For instance

( [timeofsale].[Year].[2001], [product].[all products] )

Set
A set is a collection of tuples which all have the same dimensionality

(so all have the same dimensions in the same order). Sets have {} brackets

around them, and always need them. For instance

{ ( [timeofsale].[Year].[2001], [product].[all products]

) , ( [timeofsale].[Year].[2002], [product].[all products] ) }

Function
Functions can return Sets, Tupels, Members, Levels, Dimensions or values. We'll

come across some of the more useful ones later.

Slice
We may want to cross tab by two fields for some specific value of a third, for

instance [timeofsale] by [product] for a particular [salesrep].

When we picture the report as a cube we think of this filter as a slice into

the cube, to show the values on a new face.

So that's the lexicon done, now how do we use it? Well here is the structure of a

statement

select 
{set 0} on axis(0) , /* this would be a block comment */ 
{set 1} on axis(1) , // this is a line comment 
...
{set n} on axis(n) 
from [cube]
where (tupel) 

No axis or the where statement can share any of the same

dimensions.

So if we wanted a report of [product] on columns by [salesrep] on rows we would

execute:

select 
{ ( [product].[productname].[product1] ) , 
  ( [product].[productname].[product2] ) } on columns ,
{ [salesrep].[repname]. members } on rows 
from [sales] 

Note that I've used on columns and on rows

rather than on axis(n) , because it is more clear.

On the columns I have a set with two tupels from the same dimension. The ()

brackets are not required in this case because each tupel contains just one

member. The {} are required.

The rows has a function . members , which returns a set

with all the member of that level it. As . members returns

a set we don't need the {} brackets but again I've put them in.

Here is another one:

select 
{ [product].[productname].[product1] : [product].[productname].[product20] } on columns ,
{ [timeofsale].[Year].[2002]. children } on rows 
from [sales] 

In this example I've used a range to give me a set of all the products

inclusive between [product1] and [product20] on columns. On rows I've used

another function called . children to give me all the

months in [timeofsale].[Year].[2002]

. members works on a level to give all the members at

that level.

. children works on a member to give all the members

below it (assuming there are any).

Two more useful features before we look at slices:

select 
non empty { [product].[productname]. members } on columns ,
{ { [timeofsale].[Year].[2002]. children } 
     * 
  { [salesrep].[repname]. members } } on rows 
from [sales] 

First of all the keyword non empty excludes any values

from that axis where no values are returned.

The * operator does a cross join between the two sets,

and works in a similar way to a cross join in sql. The final set will be made

up of every possible combination of the tuples in the two sets.

Now we will add a slice:

select 
{ [product].[productname]. members } on columns ,
{ [timeofsale].[Year].[2002]. children } on rows 
from [sales]
where ( [salesrep].[repname].[Mr Sales Rep1] ) 

Note that the where criteria requires a tuple rather than a slice and that tuple

cannot contain any of the same dimensions as the sets on the axis

And to finish off this introduction a list of all the MDX functions along with a

brief summary of what they do. For more detail look them up in SQL Books Online

or MDSN:

Returns a set
AddCalculatedMembersAdds calculated members to a set.
AllMembersReturns a set containing all members of a specified dimension or level,

including calculated members.

AncestorsReturns all the ancestors of a member at a specified distance.
AscendantsReturns the set of the ascendants of the member, including the member itself.
AxisReturns the set associated with the main axis.
BottomCountReturns a specified number of items from the bottom of a set, optionally

ordering the set first.

BottomPercentSorts a set and returns the bottom n elements whose cumulative total is at

least a specified percentage.

BottomSumSorts a set and returns the bottom n elements whose cumulative total is at

least a specified value.

ChildrenReturns the children of a member.
CorrelationReturns the correlation of two series evaluated over a set.
CrossjoinReturns the cross product of two sets.
DescendantsReturns the set of descendants of a member at a specified level or at a

specified distance from a member, optionally including or excluding descendants

in other levels.

DistinctEliminates duplicate tuples from a set.
DistinctCountReturns the count of tuples in a set, excluding duplicate tuples.
DrilldownLevelDrills down the members of a set, at a specified level, to one level below.

Alternatively, drills down on a specified dimension in the set.

DrilldownLevelBottomDrills down the bottom n members of a set, at a specified level, to one level

below.

DrilldownLevelTopDrills down the top n members of a set, at a specified level, to one level

below.

DrilldownMemberDrills down the members in a set that are present in a second specified set.
DrilldownMemberBottomSimilar to DrilldownMember, except that it includes only the bottom n children.
DrilldownMemberTopSimilar to DrilldownMember, except that it includes only the top n children.
DrillupLevelDrills up the members of a set that are below a specified level.
DrillupMemberDrills up the members in a set that are present in a second specified set.
ExceptFinds the difference between two sets, optionally retaining duplicates.
ExtractReturns a set of tuples from extracted dimension elements. The opposite of

Crossjoin.

FilterReturns the set resulting from filtering a set based on a search condition.
GenerateApplies a set to each member of another set and joins the resulting sets by

union.

HeadReturns the first specified number of elements in a set.
HierarchizeOrders the members of a set in a hierarchy.
IntersectReturns the intersection of two input sets, optionally retaining duplicates.
LastPeriodsReturns a set of members prior to and including a specified member.
MembersReturns the set of all members in a dimension, hierarchy, or level.
MtdA shortcut function for the PeriodsToDate function that specifies the level to

be Month.

NameToSetReturns a set containing a single member based on a string expression

containing a member name.

NonEmptyCrossjoinReturns the cross product of two or more sets, excluding empty members.
OrderArranges members of a set, optionally preserving or breaking the hierarchy.
ParallelPeriodReturns a member from a prior period in the same relative position as a

specified member.

PeriodsToDateReturns a set of periods (members) from a specified level starting with the

first period and ending with a specified member.

QtdA shortcut function for the PeriodsToDate function that specifies the level to

be Quarter.

SiblingsReturns the siblings of a member, including the member itself.
StripCalculatedMembersRemoves calculated members from a set.
StrToSetConstructs a set from a string expression.
SubsetReturns a subset of elements from a set.
TailReturns a subset from the end of a set.
ToggleDrillStateToggles the drill state of members. This function is a combination of

DrillupMember and DrilldownMember.

TopCountReturns a specified number of items from the top of a set, optionally ordering

the set first.

TopPercentSorts a set and returns the top n elements whose cumulative total is at least a

specified percentage.

TopSumSorts a set and returns the top n elements whose cumulative total is at least a

specified value.

UnionReturns the union of two sets, optionally retaining duplicates.
VisualTotalsDynamically totals child members specified in a set using a pattern for the

total label in the result set.

WtdA shortcut function for the PeriodsToDate function that specifies the level to

be Week.

YtdA shortcut function for the PeriodsToDate function that specifies the level to

be Year.

Returns a tupel
CurrentReturns the current tuple from a set during an iteration.
ItemItemReturns a member from a tuple or a tuple from a set.
StrToTupleConstructs a tuple from a string.
ValidMeasureReturns a valid measure in a virtual cube by forcing inapplicable dimensions to

their top level.

Returns a member
AncestorReturns the ancestor of a member at a specified level or at a specified

distance from the member.

ClosingPeriodReturns the last sibling among the descendants of a member at a level.
CousinReturns the member with the same relative position under a member as the member

specified.

CurrentMemberReturns the current member along a dimension during an iteration.
DataMemberReturns the system-generated data member associated with a nonleaf member.
DefaultMemberReturns the default member of a dimension or hierarchy.
FirstChildReturns the first child of a member.
FirstSiblingReturns the first child of the parent of a member.
IgnorePrevents further recursion along the dimension
LagReturns a member prior to the specified member along the member's dimension.
LastChildReturns the last child of a member.
LastSiblingReturns the last child of the parent of a member.
LeadReturns a member further along the specified member's dimension.
LinkMemberReturns a hierarchized member.
MembersReturns the member represented by the string expression
NextMemberReturns the next member in the level that contains a specified member.
OpeningPeriodReturns the first sibling among the descendants of a member at a level.
ParentReturns the parent of a member.
PrevMemberReturns the previous member in the level that contains a specified member.
StrToMemberReturns a member based on a string expression.
Returns a value or something else
AggregateReturns a calculated value using the appropriate aggregate function, based on

the context of the query.

AvgReturns the average value of a numeric expression evaluated over a set.
CalculationCurrentPassReturns the current calculation pass of a cube for the current query context.
CalculationPassValueCalculationPassValueReturns the value of an MDX expression evaluated over the specified calculation

pass of a cube.

Call UDF (args)Executes the string expression containing a user-defined function.
CoalesceEmptyCoalesceEmptyCoalesces an empty cell value to a string or number.
CountReturns the number of dimensions in a cube, the number of levels in a

dimension, the number of cells in a set, or the number of dimensions in a

tuple.

CovarianceReturns the population covariance of two series evaluated over a set, using the

biased population formula.

CovarianceNReturns the sample covariance of two series evaluated over a set, using the

unbiased population formula.

GenerateEvaluate a string expression for each member of a set
IifReturns one of two numeric or string values determined by a logical test.
LinRegInterceptCalculates the linear regression of a set and returns the value of b in the

regression line y = ax + b.

LinRegPointCalculates the linear regression of a set and returns the value of y in the

regression line y = ax + b.

LinRegR2Calculates the linear regression of a set and returns R2 (the coefficient of

determination).

LinRegSlopeCalculates the linear regression of a set and returns the value of a in the

regression line y = ax + b.

LinRegVarianceCalculates the linear regression of a set and returns the variance associated

with the regression line y = ax + b.

LookupCubeLookupCubeReturns the value of an MDX expression evaluated over another specified cube in

the same database.

MaxReturns the maximum value of a numeric expression evaluated over a set.
MedianReturns the median value of a numeric expression evaluated over a set.
MemberToStrConstructs a string from a member.
MinReturns the minimum value of a numeric expression evaluated over a set.
NameReturns the name of a dimension, hierarchy, level, or member.
OrdinalReturns the zero-based ordinal value associated with a level.
PredictEvaluates the string expression within the data mining model specified within

the current coordinates.

PropertiesReturns a string containing a member property value.
RankReturns the one-based rank of a tuple in a set.
RollupChildrenScans the children of the member parameter and applies the string expression

operator to their evaluated value.

SetToArrayConverts one or more sets to an array for use in a user-defined function.
SetToStrConstructs a string from a set.
StddevAlias for Stdev.
StddevPAlias for StdevP.
StdevReturns the sample standard deviation of a numeric expression evaluated over a

set, using the unbiased population formula.

StdevPReturns the population standard deviation of a numeric expression evaluated

over a set, using the biased population formula.

StrToValueStrToValueReturns a value based on a string expression.
SumReturns the sum of a numeric expression evaluated over a set.
TupleToStrConstructs a string from a tuple.
UniqueNameReturns the unique name of a dimension, level, or member.
UserNameReturns the domain name and user name of the current connection.
ValueValueReturns the value of a measure.
VarReturns the sample variance of a numeric expression evaluated over a set, using

the unbiased population formula.

VarianceAlias for Var.
VariancePAlias for VarP.
VarPReturns the population variance of a numeric expression evaluated over a set,

using the biased population formula.

A good place to go start trying the ideas in this article is the Foodmart

2000 database that comes as a sample when you install Analysis services.

Rate

4.43 (7)

You rated this post out of 5. Change rating

Share

Share

Rate

4.43 (7)

You rated this post out of 5. Change rating