Microsoft SQL Server 2005中的MDX脚本功能介绍

介绍
分析服务提供了一个强有力的基于服务器的计算引擎。作为一个有效的数据表技术它事实上可以做任何事。本文档描述了Microsoft SQL Server 2005多维表达式(MDX)是如何应用到日常的业务问题中的。
本文档假设读者已经了解MDX

MDX 概念
这一部份介绍了一些基本的概念。随后的部份将会做更详细的介绍。

立方体空间
属性的概念相较于Microsoft SQL Server 2000有着天壤之别。在关系型数据库中一个属性和一个维度的关系就如同一列和一张表的关系。举个例子,一个消费者维度可能包含诸如姓名, 电话号码, 性别, 城市, 州等等属性。

属性可以通过层级结构的方式展现给用户。在一个维度当中的属性层级结构包括了一个可选的“全部”级别以及属性的不同成员。举例来说,一个消费者维度可能包 含一个由两个级别组成的名称属性层级结构:“全部”级别以及一个带有每个名称成员的第二个级别。(父子层级结构的处理方式是不同的)

是属性层级结构定义了立方体的空间。你可以想象一个有着多维度空间的立方体,它是由它的属性层级结构的集合所形成的。维度是属性层级结构的容器。一个维度 也可以包括用户的层级结构来作为一个navigational convenience,但它们不会对立方体的空间产生影响。

一个属性不是必须要有一个层级结构的。如果没有创建层级结构,那么立方体的空间就是独立于属性的。举个典型的例子,一般我们不会为电话号码属性创建一个属 性层级结构,原因是通常不需要通过电话号码去查看某个维度。如果没有为属性创建一个层级结构,属性可以作为一个成员存在,而不是一个用户层级结构中的某个 级别。

浏览的恒定性
单元值是完全通过它们的属性层级结构的坐标和传递来定义的。单元值不会因浏览路径或者用户层级结构的存在与否而改变。

举个例子,由一个用户层级结构 Geography定义的单元, Customer.Geography.USA.WA.Redmond.Richard,等价于由属性层级结构 (Customer.Country.USA, Customer.State.WA, Customer.City.Redmond, Customer.Name.Richard)定义的单元.

拥有坐标 (Customer.Name.Richard) 和拥有坐标(Customer.Geography.USA.WA.Redmond.Richard)的单元是不一样的. 这是因为某个属性层级结构的一个成员并不意味着也是其它层级结构中的成员,换句话说: (Customer.Name.Richard)和 (Customer.Name.Richard, Customer.Country.All, Customer.State.All, Customer.City.All)是一样的. 尽管消费者 Richard 住在 Redmond, WA, USA, 坐标 Customer.Name.Richard 并不意味着在 City, State, 或者 Country 属性层级结构中存在坐标。

维度的叶
一个维度拥有叶。叶的含义是基于粒度属性的-这一属性将维度绑定到度量组。它常常是维度的键,但这不是必然的。例如,如果一个时间维度和一个使用日期的度量组联系在一起,日期就是粒度属性,即使时间维度有着更细致的粒度(比如,细分到分钟)

叶是与事实表中的数据直接关联的维度坐标。一个叶是由来自属性层级结构(其属性或者直接或者间接的与粒度属性相关)的成员所共同组成的,若成员是“全部” 则意味着没有成员。例如,在一个消费者维度中包含了名称(粒度属性),电子邮件,城市,州,以及国家属性,以下的维度坐标就是一个叶:
(Customer.Name.Name.Richard,
Customer.Email.Email.richard@Adventureworks.com,
Customer.City.City.Sammamish, Customer.State.State.WA,
Customer.Country.Country.USA)
然而,下面的维度坐标并不是一个叶,因为电子邮件属性层级结构中的成员是“全部”级别
(Customer.Name.Name.Richard, Customer.Email.[(All)].[All],
Customer.City.City.Sammamish, Customer.State.State.Wa,
Customer.Country.Country.USA)
如果粒度属性不是维度的键属性,叶就包括了与粒度属性无关的属性的“全部”成员。例如,如果消费者维度的粒度属性是城市属性,以下的维度坐标就是一个叶:
(Customer.Name.[(All)].[All], Customer.Email.[(All)].[All],
Customer.City.City.Sammamish, Customer.State.State.Wa,
Customer.Country.Country.USA)
注意    在单元中可能没有数据是同与粒度属性无关的属性的成员相交的。例如,如果粒度属性是城市,然后限定在一个名称属性的成员上生成空的单元。实际的行为是由在度量组上的IgnoreUnrelatedDimensions属性来决定的。

通过定义,每个粒度属性成员只有一个单叶。

Autoexists
立方体的真实空间是比它的属性层级所产生的更受限制的。有一些单元是无法存在的,原因是来自同一维度的Autoexists属性成员不能彼此并存,不能存在于这个立方体空间内。例如,(北京,加拿大)不能存在。在本文中Autoexists的概念贯彻始终。

注意     对在事实表中的数据什么也不用做。这仅仅是一个维度的概念- Autoexists仅仅属于在同一维度中的属性
可以对在立方体空间中无法存在的单元发出查询请求。例如,在语句select customer.gender.members on 0, {Customer.Name.Fred, Customer.Name.Jane} on 1 from sales中包括了在这个空间中无法存在的单元。这些单元总是空的——它们无法包含计算并且它们无法写入。

Autoexists 在查询结果中扮演了重要的角色:
•        当使用常见维度的集被投射到相同的轴时,被保留的成员可以彼此并存
例如:
Select crossjoin({Customer.Country.Country.USA}, Customer.States.States.members) on 0 from Sales
结果:只有那些在美国的州可以从Customer.States.States.members中保留下来.
•        每一个层级结构的“全部”成员可以自动和在同一维度中的所有层级结构的所有其它成员并存

子立方体
一个子立方体是一个交叉联接集的集合,它将随后的语句的空间限制到子空间。子立方体经常被引用,并且一个有效的子立方体所使用的格式有一些限制。在子立方体定义中的每个集可以是:
•        来自于一个属性层级的除了“全部”成员以外的成员的任意组合
•        一个层级结构的单个成员或者解析到一个单个成员的一个MDX表达式
•        在一个自然层级结构的一个指定级别的成员的任意组合。
注意     一个自然层级结构是由一组属性组成的,这些属性中的每一个都是它下面属性的一个成员。例如,如果城市是名称的一个成员属性,州是城市的;国家是州 的。地理层级结构,国家,州,城市,名称就是一个自然层级。层级结构性别-年龄不是一个自然层级结构,原因是性别不是年龄的一个成员属性
•        一个成员的位于多个级别的后代(仅对自然层级而言)
•        一个层级结构的“全部”成员
•        一个层级结构的叶成员
自变量“*”可以为子立方体的定义所接受。这代表了立方体的整个内容——来自每个层级结构的每个维度的每个成员

轴层级结构性
在一个查询中存在着如何将来自于同个层级结构的成员投射到不同的轴上的规则:
•        对于沿着任何轴使用通用维度但是不同的层级结构性的投射集而言不存在限制
•        使用相同层级结构性的集不能被包含在超过一个以上的轴中
注意      一个对象的层级结构性代表了在对象中呈现的层级结构

哪种方式是向上?
在SQL Server 2000分析服务中,数据从一个级别到一个级别的聚合。例如,在一个消费者维度国家,州,城市以及名称中,数据从名称到城市,然后到州,再到国家的进行聚 合。如果一个计算更改了对应雷蒙德的值(但不是针对单个的消费者),在雷蒙德之上的值将会反映这一更改;也就是说对应华盛顿,美国的值,以及全部消费者成 员将会受到影响。

在SQL Server 2005中数据聚合的方式很相似但有些微的差别,原因是一个立方体可能除了属性层级结构之外不包含任何层级结构。换句话讲,如果没有层级结构定义了“向 上”是什么含义,数据是怎样“向上”聚合的?如果消费者维度包含了不少的属性并且没有用户定义的层级结构,什么从什么聚合呢?

如果有人使用属性粒度重新检查了立方体空间,这个问题就可以回答了。在一个立方体中的每个单元都有一个对应到某个属性层级结构的粒度;单元或者位于属性 “全部”级别或者位于属性级别(在使用父子层级结构时情况可能某种程度上要更复杂一些,但原则是同样的)。一个属性层级结构的“全部”级别拥有一个比属性 层级结构级别更高的粒度。例如,成员Customer.City.[All]比Customer.City.Seattle拥有更高的粒度。

一旦我们接受了每个单元都有一个粒度的事实,我们就可以使用粒度来定义“向上”的含义:
•        如果一个单元在所有属性上有着同样的粒度那么它就和其它的单元有着同样的粒度
•        如果至少一个属性有一个更高的粒度并且其它属性都是同样或者更高的粒度的话,那么这个单元就比其它的有着更高的粒度

特别注意   在其它单元之上或之下的单元可以用比较的方式来描述。没有在其它单元之上或之下的单元被当作是不可比的;如果某些属性处于一个更高的粒度而其它属性的粒 度要低一些也是不可比单元。例如,通过元组(Customer.City.[All], Customer.Customer.Richard)定义的单元与单元(Customer.City.Sammamish, Customer.Customer.[All])是不可比的,原因是一个属性的粒度高而其它的低。

现在我们有了方向感,我们可以确定数据如何聚合:数据从低向高的粒度进行聚合
这是有帮助的,但还远没有完。怎样在一个立方体中间来插入一个计算来影响立方体进行聚合的方式?一元运算符?传递?在接下来的部份就会对此进行讨论。

MDX 脚本
一个MDX脚本是一个命令的集合,其中的每一个通过一个分号隔开。脚本是用来生成一个使用计算的立方体的。
这部份描述了在MDX脚本后面的一些关键概念以及一些对常见的计算有所帮助的新功能

执行对声明
脚本看上去象一个程序一样执行。事实上,同样的概念在分析服务2000中已经使用了(比如传递以及解析顺序)但是被放到了一个不为注意的位置。MDX的脚本并不真正的“运行”。它是一套总是有效的被声明的命令。立方体的内容总是和脚本一致。

传递
在传递0,立方体仅仅包含事实和写回的数据。脚本产生传递 0以后的数据。
每一个脚本中的赋值,冻结以及计算语句都产生一个新的传递
计算成员存在于所有的传递中而无论其创建在哪个传递中。

没有脚本
如果没有定义脚本,立方体采用一个缺省的使用单命令计算的隐性脚本。
如果脚本存在但是空白的,一个空白的脚本会使用但什么也不计算。

创建计算
一个简单的定义一个计算单元的方法是:
= ;
示例:
(Sales,Budget) = (Sales,Actual) * 1.2;
Sales = Sales *1.2 ;
每个赋值创建了它自身的传递,用来阻止无限递归。
当某个表达式引起无限递归时,来自前面的传递值被采用。例如:
Sales = Sales * 1.2
等价于
Sales = CalculationPassValue(Sales, -1, RELATIVE) * 1.2
对传递的明确参照是允许的但不推荐,原因是当脚本更改时传递号也会更改。
计算在一个更高的粒度更改结果——确切是如何的在后面讨论。

范围
一个范围限定对应一个子立方体的语句。如果没有指定的范围,默认的范围是整个的立方体。
BNF
Scope();

...
End Scope;
:== refer to the definition of a subcube
范围的定义是静态的。例如,设想一个带有一个消费者维度的立方体扮演了两个角色: SoldTo 和 PurchasedFrom。为了定义一个关于谁将产品卖给了消费者的子立方体,下面的方法不会象预料的那样工作:
Scope (SoldTo.Name.Name.members);
   Scope(LinkMember(SoldTo.Name.CurrentMember, PurchasedFrom.Name));
      ...
   End Scope;
End Scope;
它之所以不工作是因为定义第二个范围的语句没有在每一单元中重新评估;表达式SoldTo.Name.CurrentMember在原始的范围上不是动态的


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12921506/viewspace-201765/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/12921506/viewspace-201765/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值