| xiaoxinlucky | | 2008-2-20 06:31 |
|
Microsoft SQL Server 2005中的MDX脚本功能介绍
[quote][b]摘要[/b]
本文描述了Microsoft SQL Server 2005的多维表达式(MDX)如何才能适用于日常的业务问题。本文档假设读者已经了解MDX[/quote]
[quote][b]内容列表[/b]
介绍
MDX 概念
立方体空间
浏览的恒定性
维度的叶
Autoexists
子立方体
轴层级结构性
哪种方式是向上?
MDX 脚本
执行对声明
传递
没有脚本
创建计算
范围
BNF
示例
嵌套
This
冻结语句
BNF
计算语句
BNF
Root
BNF
一个立方体如何聚合[/quote] |
| xiaoxinlucky | | 2008-2-20 06:35 |
|
[quote][b]介绍[/b]
分析服务提供了一个强有力的基于服务器的计算引擎。作为一个有效的数据表技术它事实上可以做任何事。本文档描述了Microsoft SQL Server 2005多维表达式(MDX)是如何应用到日常的业务问题中的。
本文档假设读者已经了解MDX
[b]MDX 概念[/b]
这一部份介绍了一些基本的概念。随后的部份将会做更详细的介绍。
[b]立方体空间[/b]
属性的概念相较于Microsoft SQL Server 2000有着天壤之别。在关系型数据库中一个属性和一个维度的关系就如同一列和一张表的关系。举个例子,一个消费者维度可能包含诸如姓名, 电话号码, 性别, 城市, 州等等属性。
属性可以通过层级结构的方式展现给用户。在一个维度当中的属性层级结构包括了一个可选的“全部”级别以及属性的不同成员。举例来说,一个消费者维度可能包含一个由两个级别组成的名称属性层级结构:“全部”级别以及一个带有每个名称成员的第二个级别。(父子层级结构的处理方式是不同的)
是属性层级结构定义了立方体的空间。你可以想象一个有着多维度空间的立方体,它是由它的属性层级结构的集合所形成的。维度是属性层级结构的容器。一个维度也可以包括用户的层级结构来作为一个navigational convenience,但它们不会对立方体的空间产生影响。
一个属性不是必须要有一个层级结构的。如果没有创建层级结构,那么立方体的空间就是独立于属性的。举个典型的例子,一般我们不会为电话号码属性创建一个属性层级结构,原因是通常不需要通过电话号码去查看某个维度。如果没有为属性创建一个层级结构,属性可以作为一个成员存在,而不是一个用户层级结构中的某个级别。[/quote]
[quote][b]浏览的恒定性[/b]
单元值是完全通过它们的属性层级结构的坐标和传递来定义的。单元值不会因浏览路径或者用户层级结构的存在与否而改变。
举个例子,由一个用户层级结构 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 属性层级结构中存在坐标。
[b]维度的叶[/b]
一个维度拥有叶。叶的含义是基于粒度属性的-这一属性将维度绑定到度量组。它常常是维度的键,但这不是必然的。例如,如果一个时间维度和一个使用日期的度量组联系在一起,日期就是粒度属性,即使时间维度有着更细致的粒度(比如,细分到分钟)
叶是与事实表中的数据直接关联的维度坐标。一个叶是由来自属性层级结构(其属性或者直接或者间接的与粒度属性相关)的成员所共同组成的,若成员是“全部”则意味着没有成员。例如,在一个消费者维度中包含了名称(粒度属性),电子邮件,城市,州,以及国家属性,以下的维度坐标就是一个叶:
(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属性来决定的。
通过定义,每个粒度属性成员只有一个单叶。
[b]Autoexists[/b]
立方体的真实空间是比它的属性层级所产生的更受限制的。有一些单元是无法存在的,原因是来自同一维度的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中保留下来.
• 每一个层级结构的“全部”成员可以自动和在同一维度中的所有层级结构的所有其它成员并存
[b]子立方体[/b]
一个子立方体是一个交叉联接集的集合,它将随后的语句的空间限制到子空间。子立方体经常被引用,并且一个有效的子立方体所使用的格式有一些限制。在子立方体定义中的每个集可以是:
• 来自于一个属性层级的除了“全部”成员以外的成员的任意组合
• 一个层级结构的单个成员或者解析到一个单个成员的一个MDX表达式
• 在一个自然层级结构的一个指定级别的成员的任意组合。
注意 一个自然层级结构是由一组属性组成的,这些属性中的每一个都是它下面属性的一个成员。例如,如果城市是名称的一个成员属性,州是城市的;国家是州的。地理层级结构,国家,州,城市,名称就是一个自然层级。层级结构性别-年龄不是一个自然层级结构,原因是性别不是年龄的一个成员属性
• 一个成员的位于多个级别的后代(仅对自然层级而言)
• 一个层级结构的“全部”成员
• 一个层级结构的叶成员
自变量“*”可以为子立方体的定义所接受。这代表了立方体的整个内容——来自每个层级结构的每个维度的每个成员[/quote]
[quote][b]轴层级结构性[/b]
在一个查询中存在着如何将来自于同个层级结构的成员投射到不同的轴上的规则:
• 对于沿着任何轴使用通用维度但是不同的层级结构性的投射集而言不存在限制
• 使用相同层级结构性的集不能被包含在超过一个以上的轴中
注意 一个对象的层级结构性代表了在对象中呈现的层级结构
[b]哪种方式是向上?[/b]
在SQL Server 2000分析服务中,数据从一个级别到一个级别的聚合。例如,在一个消费者维度国家,州,城市以及名称中,数据从名称到城市,然后到州,再到国家的进行聚合。如果一个计算更改了对应雷蒙德的值(但不是针对单个的消费者),在雷蒙德之上的值将会反映这一更改;也就是说对应华盛顿,美国的值,以及全部消费者成员将会受到影响。
在SQL Server 2005中数据聚合的方式很相似但有些微的差别,原因是一个立方体可能除了属性层级结构之外不包含任何层级结构。换句话讲,如果没有层级结构定义了“向上”是什么含义,数据是怎样“向上”聚合的?如果消费者维度包含了不少的属性并且没有用户定义的层级结构,什么从什么聚合呢?
如果有人使用属性粒度重新检查了立方体空间,这个问题就可以回答了。在一个立方体中的每个单元都有一个对应到某个属性层级结构的粒度;单元或者位于属性“全部”级别或者位于属性级别(在使用父子层级结构时情况可能某种程度上要更复杂一些,但原则是同样的)。一个属性层级结构的“全部”级别拥有一个比属性层级结构级别更高的粒度。例如,成员Customer.City.[All]比Customer.City.Seattle拥有更高的粒度。
一旦我们接受了每个单元都有一个粒度的事实,我们就可以使用粒度来定义“向上”的含义:
• 如果一个单元在所有属性上有着同样的粒度那么它就和其它的单元有着同样的粒度
• 如果至少一个属性有一个更高的粒度并且其它属性都是同样或者更高的粒度的话,那么这个单元就比其它的有着更高的粒度
特别注意 在其它单元之上或之下的单元可以用比较的方式来描述。没有在其它单元之上或之下的单元被当作是不可比的;如果某些属性处于一个更高的粒度而其它属性的粒度要低一些也是不可比单元。例如,通过元组(Customer.City.[All], Customer.Customer.Richard)定义的单元与单元(Customer.City.Sammamish, Customer.Customer.[All])是不可比的,原因是一个属性的粒度高而其它的低。
现在我们有了方向感,我们可以确定数据如何聚合:数据从低向高的粒度进行聚合
这是有帮助的,但还远没有完。怎样在一个立方体中间来插入一个计算来影响立方体进行聚合的方式?一元运算符?传递?在接下来的部份就会对此进行讨论。[/quote]
[quote][b]MDX 脚本[/b]
一个MDX脚本是一个命令的集合,其中的每一个通过一个分号隔开。脚本是用来生成一个使用计算的立方体的。
这部份描述了在MDX脚本后面的一些关键概念以及一些对常见的计算有所帮助的新功能
[b]执行对声明[/b]
脚本看上去象一个程序一样执行。事实上,同样的概念在分析服务2000中已经使用了(比如传递以及解析顺序)但是被放到了一个不为注意的位置。MDX的脚本并不真正的“运行”。它是一套总是有效的被声明的命令。立方体的内容总是和脚本一致。
[b]传递[/b]
在传递0,立方体仅仅包含事实和写回的数据。脚本产生传递 0以后的数据。
每一个脚本中的赋值,冻结以及计算语句都产生一个新的传递
计算成员存在于所有的传递中而无论其创建在哪个传递中。
[b]没有脚本[/b]
如果没有定义脚本,立方体采用一个缺省的使用单命令计算的隐性脚本。
如果脚本存在但是空白的,一个空白的脚本会使用但什么也不计算。
[b]创建计算[/b]
一个简单的定义一个计算单元的方法是:
<subcube definition> = <expression>;
示例:
(Sales,Budget) = (Sales,Actual) * 1.2;
Sales = Sales *1.2 ;
每个赋值创建了它自身的传递,用来阻止无限递归。
当某个表达式引起无限递归时,来自前面的传递值被采用。例如:
Sales = Sales * 1.2
等价于
Sales = CalculationPassValue(Sales, -1, RELATIVE) * 1.2
对传递的明确参照是允许的但不推荐,原因是当脚本更改时传递号也会更改。
计算在一个更高的粒度更改结果——确切是如何的在后面讨论。
[b]范围[/b]
一个范围限定对应一个子立方体的语句。如果没有指定的范围,默认的范围是整个的立方体。
BNF
Scope(<subcube definition>);
<statement>
...
End Scope;
<subcube definition> :== 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在原始的范围上不是动态的[/quote] |
| xiaoxinlucky | | 2008-2-20 06:40 |
|
[quote][b]示例[/b]
接下来的几个示例是关于一个立方体的,它有两个维度:Customer 和 Measures。Measures维度有一个度量值,Sales。Customer维度有两个属性:Country 和 City (粒度属性);以及3个层级结构:两个属性层级结构以及一个用户层级结构Geography。Country有成员USA 和 England; City: Seattle, Redmond, London 以及 Leeds。下面的表显示了对一个范围和赋值的影响。
值得注意的是在下面的示例中没有计算语句。在立方体中的数据是没有聚合的,所有的更改都仅仅是因为赋值
为了简略,维度名从成员名称上省略了。
示例 1
Scope(Customer.Country.Country.USA, *);
Sales = 2;
End Scope;
查询:
如果某人通过属性层级来观察数据,他将会看到:
[attach]73284[/attach]
在这个例子中,在通过(City.London, Country.USA)定义的单元中没有值,因为它不存在。
示例 2
Scope(Customer.City.City.Redmond, *);
Sales = 4;
End Scope;
在属性层级中的销售数据:
[attach]73285[/attach]
示例 3
Scope(Geography.USA.Redmond, *)
Sales = 32;
End Scope;
[attach]73286[/attach]
[attach]73287[/attach][/quote]
[quote][b]嵌套[/b]
嵌套范围语句会继承父范围(除非一个属性被重新设置了范围)。例如:
Scope(Customers.Country.USA);
Scope(Customers.State.Or);
Scope(Customers.Gender.Male);
<scope is USA, Or, Male>
End Scope;
End Scope;
End Scope;
一个scope语句可以对在一个父范围内的层级结构重新设置范围。例如:
Scope(Customers.Country.USA);
Scope(Customers.State.Or);
Scope(Customers.State.Wa);
<scope is Wa, USA>
End Scope;
<scope is Or, USA>
End Scope;
End Scope;
This
关键字This代表当前的子立方体。例如,以下的代码将在USA 和 Canada中的Sales设为2:
Scope(Sales, {USA, Canada});
This = 2;
End Scope;
应注意的是This不能用在赋值的右边。
[b]冻结语句[/b]
在脚本中,用户可能想要更改之前在一个表达式中用过的单元的值来确定其它单元的结果,不过又不想在作出更改的同时改变了以前计算的结果。
BNF
Freeze [<subcube>]
Freeze语句让单元保持它们当前的值。对其它单元所做的更改没有任何影响。
例如:
B = 2;
A = B;
B = 3;
此时 A 和B 都等于 3.
B = 2;
A = B;
Freeze(A);
B = 3;
此时 A = 2 而 B =3.
换句话说,在传递‘P’上的Freeze(<scope>)逻辑等价于将表达式赋给单元CalculationPassValue(<scope>, p, ABSOLUTE)。
[b]计算语句[/b]
对于非叶单元的单元计算是隐性的通过立方体的维度结构进行的。最常见的是一个简单的聚合,不过一个维度可以定义一元运算符和自定义的成员以及级别计算。
更进一步的,每个维度可以包含一个不同的公式以及它们的应用顺序来改变聚合的结果。Calculate命令为立方体提供了依照其缺省的方式聚合的方法或者可被用来更好的控制维度聚合的顺序。
在Calculate命令应用之前一个非叶单元的内容是空值;这就是说,在Calculate命令被用来使用一个公式填充单元之前没有单元有公式。
BNF
Calculate;
Calculate对计算成员没有影响
Root
返回在来自每个属性的“全部”成员的交叉点上的元组。如果某个属性没有一个“全部”成员,Root返回缺省成员。
BNF
Root()
返回在来自立方体中每个属性的“全部”成员的交叉点上的元组。如果没有“全部”成员,将返回一个顶级级别的成员。
Root(<dimension>)
返回在来自维度中每个属性的“全部”成员的交叉点上的元组
Root(<tuple>)
返回在来自被包含在元组中的每个属性的“全部”成员的交叉点上的元组
例如,一个计算某个特定产品SKU的利润百分比的计算成员与一个计算所有产品利润百分比的计算成员的对比如下:
Create Member [Profit%] AS
([Profit %], [Product].[SKU].[SKU].currentmember) /
([Profit %], Root(Product))
Root在当前成员的上下文中工作。本质上,它会取所有的层级结构的当前成员的根祖先。如果在所有的层级结构中都有“全部”成员,那么真正最根上的就是“全部”。不过在没有“全部”成员的情况下,它将会找到当前成员的根祖先。例如:
Root(Time) 将会产生 [2002] 如果 time.currentmember 是 [25-Feb-2002].
[b]一个立方体如何聚合[/b]
在大多数情况下,一个立方体聚合的方式“只是跟着感觉走”。不过如果你试图做一些复杂的操作来控制它,了解规则是有帮助的。[/quote]
[quote][b]最后的传递胜出[/b]
无论何时一个多值赋值应用到同样的单元,最后的传递会优先一些。
它应用到单元在赋值的范围或者在赋值的范围以上。例如,看一下下面的脚本:
Calculate;
(Customer.Name.[All], Customer.City.[All], Customer.State.[All],
Customer.Country.[All]) = 100;
(Customer.Name.[Richard], Customer.City.[Sammamish], Customer.State.[Wa],
Customer.Country.[USA]) = 1;
在(Customer.Name.[All], Customer.City.[All], Customer.State.[All], Customer.Country.[All])单元的值会用1加上来自事实表中除了Richard以外的消费者的数据。在低粒度的赋值的聚合优先于在之前的传递于更高粒度的赋值的聚合
[b]最接近的胜出[/b]
最后的传递胜出的规则应用到赋值,但不应用到诸如一元运算符和自定义成员公式这样的维度计算。此时应用的是最接近的胜出的规则。
如果一个单元在一个维度计算和一个赋值之上,单元的值是从最接近的计算中求得的。
例如,假设一个立方体有一个带有一元运算符的帐户层级结构和一个有两个成员的产品层级结构。计算语句聚合事实数据如下所示:
[attach]73288[/attach]
现在考虑一下以下赋值的效果:
(Account.[All Accounts], Product.[Drinks] ) = 100;
[attach]73289[/attach]
单元(Account.[All Accounts], Products.[All Products])的值始终是5,因为一元运算符是最接近的(右上方)。
考虑如果换成以下赋值:
(Account.[Expense], Product.[Drinks] ) = 1000;
[attach]73290[/attach]
在(Account.Expense, Products.[All Products])单元的值从赋值聚合而来,因为它在一个更高的粒度并且没有其它的计算影响它(一元运算符影响一个成员如何聚合到它的父代以及在成员自己上没有一个计算)。
由于在如何进行所谓的维度计算(一元运算符以及自定义的成员公式)方面存在差异,维度计算不能单纯的仿效赋值。[/quote]
[[i] 本帖最后由 xiaoxinlucky 于 2008-2-20 14:44 编辑 [/i]] |
| xiaoxinlucky | | 2008-2-20 06:45 |
|
[quote][b]Copyright[/b]
该白皮书为初步文档,可能会在所述软件进行最后商业发布之前做完全修改。
该文档所含信息代表微软公司在文档出版时对所论及问题的当前看法。由于微软必须对千变万化的市场情况做出相应反应,因此本文档不应视为微软的任何承诺,且微软不保证所陈述任何信息在产品发布后的准确性。
本白皮书仅供信息参考。微软对本文件中的信息不做任何明示或默示保证。
遵守所有适用的版权法律是用户应尽的责任。下述陈述不限制任何版权,在未获得微软公司明示书面许可的情况下,不得以任何目的复制本文档任何部分或将任何部分保存或引入检索系统、亦不得以任何形式(电子、机械、影印、录制或其他方式)进行传播。
微软在文件所述主题中拥有专利权、专利应用程序、商标、版权或其他知识产权。除非在微软的任何书面许可协议中明示规定,否则对本文档的提供不得视为对任何专利权、商标、版权或其他知识产权许可的提供。
除非特别声明,本文中描述的示例公司、组织、产品、域名、e-mail地址、徽标、人物、地点以及事件均为虚构的,不应与任何实际的公司、组织、产品、域名、e-mail地址、徽标、人物、地点以及事件有任何的联系。
© 2005微软公司版权所有。
Microsoft和ActiveX是微软公司在美国和其他国家的注册商标或商标。
本文中实际公司和产品的名称可能是其相应所有者的商标。[/quote] |
|
| 学习了,不知道是否还有人提供具体的详实介绍或者相关方面的资料? |
关键词: c
相关文章: oracleOracle 9i在AIX上的性能調整 BBC:2029年有望实现人机合体 绝对有用 巧用批处理和reg文件制作“假”病毒,请勿乱用 **提供网络推广工具
Powered by 51CTO.COM
|