MDX语句(MultiDimensionalExpressions)是一种语言,支持多维对象与数据的定义和操作。它可以表达在线分析出来数据卡上的选择、计算和一些元数据定义等操作,并赋予用户表现查询结果的能力。
MDX是由Microsoft,Hyperion等公司研究多维查询表达式,是所有OLAP高级分析所采用的核心查询语言。
如同SQL查询一样,每个MDX 查询都要求有数据请求(SELECT子句)、起始点(FROM子句)和筛选(WHERE子句)。这些关键字以及其它关键字提供了各种工具,用来从多维数据集析取数据特定部分。MDX还提供了可靠的函数集,用来对所检索的数据进行操作,同时还具有用户定义函数扩展 MDX的能力。
1、MDX查询语句
查询所需要的数据。
2、MDX表达式
定制需要的指标。
3、MDX脚本
指定流程由SQL执行生成自定义的效果。
1、多维数据集
2、度量值(量度)
3、维度
4、维度的层次结构
5、维度的级别
6、成员(Member)
指的是维度树上的一个节点,这里有一点需要指出,量度也是一个特殊的维度,所以对于普通维度上的 Member可以有几下几种表示方法: [Customer] 或 [Time].[1996] 等,对于特殊的维度——量度而言,也可以表示一个 Member,如: [Measures].[unitsales] 等。
标识符:[ ]
7、元组(Tuple)
是由若干个Members组成,CUBE上的一个子集(不断开的子CUBE),每一个维度上最多只能有一个 Member,对于一个 Tuple而言至少有一个维度,多则不限,顺序无关,同时对于没有列出来的那就表示为默认的 Member。
标识符:()
示例:
a) ([Regin ].[USA])
b) ([product].[computers],[time].[2008]) 。
8、集(Set)
同一维度上若干个 Members的集合,或者是若干个 Tuples的集合,但这里有一个地方需要注意,那就是如果是若干个 Tuple组成的集合是,各个 Tuple里的 Member之间存在着一定的对应关系。集合的表示方法用大括号“ {} ”,所以可能的表示方法为:
a) {[time].[2008],[time].[2009],[time].[2000]} ,这里 Set是由 同一维度的若干个 Member组成。
b) {([computer],[usa ]),([mobile],[china])} ,这个 Set是由两个 Tuples组成,这里大家可以看到,在第一个 Tuple当中,第一个 Member是名为 computer的产品,所以后面的 Tuple的第一个 Member也必须是一个产品,所以我们这里看到的是 mobile,第一个 Tuple里第二个 Member是一个国家,所以第二个 Tuple的第二个 Member也必须是一个国家名,依次类推。
标识符:{ }
一个标准的 MDX查询语句就是由我们前面介绍的 MDX的三个基本对象构成,也就是 Member、 Tuple、 Set。
1、SELECT SET ON COLUMNS,
SET ON ROWS
FROM CUBE
WHERE TUPLE
2、SELECT SET ON 0,
SET ON 1
FROM CUBE
WHERE TUPLE
想象一个简单的带有时间、销售地点和度量3个维度的多维数据集,该多维数据集的名称为销售额(即SALES)。其中度量包括销售额和成本。假如想查看2005年前两个季度马萨诸塞州的销售额与成本,如图所示。
我们可以通过下面的MDX获得想要的数据:
SELECT {[MEASURES].[DOLLAR SALES],[MEASURES].[UNIT SALES]} ON COLUMNS,
{[TIME].[2005].[Q1], [TIME].[2005].[Q2]} ON ROWS
FROM [SALES]
WHERE ([CUSTOMER].[MA])
MDX查询的结果本身是一个网格,本质上是另一个多维数据集。下面将这个简单的查询拆开来仔细研究。
关键字SELECT后带需要检索内容的子句。
关键字ON和轴的名称一起使用,以指定数据库的维度显示位置。该示例查询将度量显示为列,将时间段显示为行。
MDX用大括号{ }引用来自某个特点维度或者多个维度的一组元素。这个简单的查询在其两个轴中的每一个上都只有一个维度(度量维度和时间维度)。元素间用逗号隔开。元素名称用方括号引用,并且不同组成部分之间用点号分隔。
MDX能够的FROM子句指明用于查询数据的多维数据集。这与SQL中的FROM子句类似。
WHERE子句指定在列或行(或者其他轴上)不出现的多维数据集其他维度的成员。如果不对某个维度指定一个成员,MDX将使用默认成员。WHERE子句是可选的。
提示:MDX不是大小写敏感的,可以随心所欲的混用字母大小写。
1、逗号(,)与冒号(:)
可以通过枚举元素并用逗号来隔开构造一个集,例如上面示例中用到的例子。
{[TIME].[2005].[Q1], [TIME].[2005].[Q2]}
该表达式产生一个包含2005年第一季度和第二季度的集。
冒号用同一级别的两个成员作为端点,来表示这两个端点间的所有成员(与EXCEL中的指定单元格范围的用法类似)。在冒号两边可以是相同的成员,表示集中只有一个成员。例如:
{[TIME].[2005].[SEP]: [TIME].[2006].[MAR]}
该表达式表示从2005年9月到2006年3月的所有月份。
2、.MEMBERS 获取所有成员
无论用于检索,还是作为更复杂的操作的基础,获得一个维度、层次结构或者级别的成员的集是非常普遍的操作。维度、层次结构或者级别放置在.MEMBERS操作符的左边,可以返回由该元数据范围内所有成员构成的集。
例如:
[TIME].[MONTHS].MEMBERS
该表达式返回时间维度下的月这一级别的所有成员(即所有月份)。
3、.PREMEMBER获取指定成员的前一个成员
4、.NEXTMEMBER获取指定成员的后一个成员
5、使用.CHILDREN获得一个成员的子成员
另外一个常用的查询时获得一个成员的子成员。这么做的目的可能是执行一个向下钻的操作,或者为了方便的获得基于一个共同父成员的范围内的成员。例如:
[TIME].[YEARS].[2005].CHILDREN
该表达式返回2005年的所有孩子(即2005年的所有月份)。
6、.FIRSTCHILD 获取指定成员的第一个子成员
7、.LASTCHILD获取指定成员的最后一个子成员
1、DESCENDANTS() 获取一个成员的后代成员。
直接子代之下的后代成员,可以使用DESCENDANTS()。
语法:
DESCENDANTS(MEMBER,LEVEL,FALG)
返回MEMBER之下与LEVEL相关的成员,并且可选参数FLAG。
FLAG的可选值有:
SELF
BEFORE
AFTER
SELF_AND_BEFORE
SELF_AND_ AFTER
SELF_ BEFORE _BEFORE
LEAVES
SELF仅仅指MEMBER以下LEVEL级别上的成员,这是最常用的选项,如果忽略FLAG参数,那么默认使用SELF。例如:
DESCENDANTS([TIME].[YEARS].[2005],[TIME].[MONTH])
该将返回2005年的所有月份。
SELF_AND_BEFORE将返回MEMBER所在级别已经LEVEL级别之间的所有成员,也就是包含MEMBER在内、从LEVEL级别到MEMBER级别的所有成员。例如:
DESCENDANTS([TIME].[YEARS].[2005],[TIME].[MONTHS],
SELF_AND_BEFORE)
该表达式将返回2005年及该年的所有季度和所有月份。
2、FILTER() 过滤
FILTER()函数用来缩减集(过滤),它表示在结果集中只包含那些符合特定标准的元素。FILTER()采用一个集和一个布尔表达式作为它的参数,并且当布尔表达式为真时,返回该集的子集。
语法:
FILTER(SET,BOOLEAN-EXPRESSION)
例如:
FILTER({[PRODUCT].[PRODUCTCATEGORY].MEMBERS},
[MEASURES].[DOLLARSALES]>=500)
该表达式将返回相关美元销售额在500元以上的某类产品构成的集。
FILTER()可以操作元组构成的任何集,而不仅仅是以个维度的成员构成的集。
3、ORDER() 排序
ORDER()用来根据相关数据值给集的元组排序。
语法:
ORDER (SET,EXPRESSION,FLAG)
ORDER()的参数包括一个集、排序标准,还有一个可选的标志,该标志指示排序原则(升序或降序,包含或者忽略元组间的层次关系)。ORDER()返回的集由原来的集的元组构成,但按照新指定的顺序重新排序。
例如:
ORDER([PRODUCT].[PRODUCTCATEGORY].MEMBERS},
[MEASURES].[DOLLARSALES],BDESC)
该表达式将按销售额对产品进行降序排序(BDESC将忽略层次结构)。
4、.CURRENTMEMBER 获取当前成员
语法:
DIMENSION.CURRENTMEMBER
返回该维度的当前成员。
5、.PARENT 获取指定成员的父对象成员
语法:
MEMBER.PARENT
返回对给定成员的父对象成员。
6、NONEMPTY去除空切片
在一个多维空间中,数据稀疏现象很常见。MDX中提供了从查询的结果中移除完全为空的切片的方法,那就是使用NONEMPTY关键字。去除空切片需要做的仅仅是在待移除空切片的轴前面加上NONEMPTY关键字。NONEMPTY可以用在任何轴、维度和元组上。
7、去年同期的引用和计算
一个经常会用到的计算是查询一年前同一时期的数据,或者上一个季度同一时期和上周同一天的数据。可以使用PARALLELPERIOD()函数。
语法:
PARALLELPERIOD(LEVEL,INDEX,MEMBER)
该函数首先的到级别LEVEL中成员MEMBER的主席,然后从该祖先的兄弟成员中找到编号比该祖先小INDEX的成员(称为姻亲),最后返回该姻亲的后代成员中MEMBER的堂兄弟。
例如:
PARALLELPERIOD([YEARS],1,[MAY2006])
将返回[MAY2005]