微软bi教程学习mdx语法_第1页
微软bi教程学习mdx语法_第2页
微软bi教程学习mdx语法_第3页
微软bi教程学习mdx语法_第4页
微软bi教程学习mdx语法_第5页
已阅读5页,还剩17页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、SQLServer 商业智能系列:MDX 基础(1)一、MDXMDX 是一种和 SQL 类似的语言,它也可以用于查询、计算和定义一些元数据。只不过 SQL是基于 OLTP 的,而 MDX 是基于 OLAP 的,也就是说,MDX 是对数据进行查询的。和其它的 OLAP语言不同,MDX 并不完全是一种形式语言。但用 MDX 查询出来的结果仍然可以在客户端程序中以表格形式进行展现。MDX 和 SQL 一样,也有很多不同功能的 API 来支持 MDX。其中包括对象和为分析处理的内嵌数据功能(也就是 OLE DB for OLAP)、ADO MD、ADOMD.Net、XMLA(XMLforysis)等。

2、OLE DB for OLAP 的规范描述了 MDX 查询和将被查询给客户端的数据结构之间的完整关系。二、第一次使用 MDX在本节中,按着步骤来执行一系列简单的 MDX 查询。通过对本节的学习,读者可以很轻松地将 MDX 的概念转化为实际的例子。可以想象有一个非常简单的立方体,这个立方体有三个维度,分别代表时间、地理位置和销售业绩。给这个立方体起名为 Sales。现在让的一个表格。这个表格中的数据是在 2007 年头两个季度在的销售量和销售额。这个表格有两个维度,就象一个电子表格一样,但是在第一列表示了两个维度,因此,这个表格实际上是三个维度。表格如表 1-1所示:表 1-1下面的 MDX 查

3、询将从 OLAP 中获得表 1-1 的内容:在上面的查询中,涉及到了 SELECT、FROM 和 WHERE 关键字,这些关键字代表了不同的部分。MDX查询的结果本身是一个表格,实际上是另外一个立方体。要查询的维度作为结果集的列。这个查询应用了两个被命名的行和列。在 MDX 技术中,一个轴是一个边或一个查询结果集的维度。使用轴要比直接使用立方体体的维度更简单,而且每个轴还可以是多个立方体维度的组合。可以根据上面的语句将这个例子泛化。现在让这个查询分成以下几部分:1. SELECT 子句是 MDX 语句的开始,用于指定想要获得什么信息。2. ON 关键字后面跟着用于指定维度的轴的名称。在这个例子

4、中将销售业绩放到 columns 轴上,将时间信息放到 row 轴上。3. MDX 使用上卷括号和来装入从一个特定的维度或维度集合中装入数据。在的例子中在每个查询中只有一个维度。用多个“.”进行分割。可以使用逗号来分割不同的元素。元素名可以放到中,可以使SELECT Measures. 销售金额, Measures.销售数量 on columns, Time.Q1, 2007, Time.Q2, 2007 on rows FROM SalesWHERE (Customer.MA)销售金额销售数量Q1, 2007102,949.103,462Q2, 200789,125.122,1564. 在一

5、个 MDX 查询中,指定了维度如何从的数据库中到的结果集轴上。在这个查询中是销售业绩在了 columns 轴上,而时间在了 rows 轴上。每一个查询可以用不同数量的结果集轴。前三个轴的名为columns,rows和pages,这些轴从形式上和报表的格式一致。一个 MDX 查询中的 FROM 子句用于指定被查询的数据的名称。这和 SQL 语句中的 FROM 子句类似。WHERE 子句提供了一种用于指定在当前立方体中未出现维度的方法。如果不指定其它的维度,那么MDX 将使用默认的维度。因此,WHERE 子句对于 MDX 查询是可选的。一但数据库已经确定了查询结果集的单元格,就会将从立方体中查询出

6、来的数据这些单元格。MDX 和 SQL 都拥有 SELECT、FROM 和 WHERE 关键字。但要注意的是,这三个关键字和 SQL 中的并不一样,在学习 MDX 时最好忘记 SQL 中的这几个关键字。这是因为它们的含义和语法不相同,如果试着将 SQL 中的这些关键字的经验应用到 MDX 中,是非常不明智的。下面让来看另外一个例子。为了产生表 1-2 的结果集,可以写如下的 MDX 语句:表 1-2可以从上面的代码看到,时间、位置和销售业绩仅仅被 columns 上的时间列表、rows 上的客户和 WHERE 部分的销售业绩选择。三、轴的应用有很想通过“on columns/rows/”等语法

7、将很多成员放到 columns 或rows 或是查询结果集的其他轴里。对于轴的表示可以通过指定轴的名称,如下面的 MDX 表达式:还可以使用数字索引来查询中的轴,代码如下: Time.Q1, 2005, Time.Q2, 2005, Time.Q3, 2005 on axis(0),Customer.MA, Customer.CT on axis(1)SELECTCustomer.MA, Customer.CT on rows, Time.Q1, 2005, Time.Q2, 2005, Time.Q3, 2005 on columns FROM SalesWHERE ( Measures.D

8、ollar Sales )Q1,2007Q2,2007Q3,2007MA96,949.1012,688.40104,510.20CT24,660.7091,025.0016,643.90SELECT Time.Q1, 2007, Time.Q2, 2007, Time.Q3, 2007 on columns, Customer.MA, Customer.CT on rowsFROM SalesWHERE ( Measures.销售额 )axis(n)的表达形式确定这些成员将被放到序号为 n 的辆上。对于没有名称的轴,必须使用索引来轴。还可以在查询中混合使用索引和名称,代码如下:然而,一个使用轴

9、的查询还必须使用索引为 0 的轴,并且一个使用轴 2 的查询必须使用轴 1 和 0。否则将会出现错误。如以下的代码将抛出一个错误:四、MDX 语法基础在这一节让学下 MDX 频繁使用的一些操作符和函数。介绍它们,并描述它们常用的使用方法。下面是本节将介绍的内容。1逗号(,) and 冒号 (:) 2.Members3.Children 和 Descendants()逗号(,) and 冒号 (:)到现在为此已经看到逗号操作符被应用到了 Mdx 语句中;现在让学习的关于逗号的知识。首先可以使用逗号来分割组件和它的属性。如下面的代码如示: Time.January 2007, Time.Febru

10、ary 2007,Time.March 2007 上面语句的功能是列出 2007 年头三个月数据。在每一个维度的第一层的成员通常按着一个顺序排列(通常是按着 key 或是名称进行排列)。根据这个顺序,可以将两个成员中间的数据作为一个集合列出。而集合的两端就是两个成员。这两个成员使用冒号(:)分割。这有些和在Excel 中指定单元格之间的范围类似。如下面的查询的结果是列出 2005 年 9 月和 2007 所 10 月的月份以及在产生目录中从 Tools 到 Audio的数据。代码如下:SELECT Time.Sep,2005 : Time.Oct,2007 on columns, Produc

11、t.Tools : Product.Home Audio on rows FROM SalesSELECTCustomer.MA, Customer.CT on axis(2), Time.Q1, 2005, Time.Q2, 2005, Time.Q3, 2005 on axis(0) FROM SalesWHERE ( Measures.Dollar Sales )SELECTCustomer.MA, Customer.CT on rows, Time.Q1, 2005, Time.Q2, 2005, Time.Q3, 2005 on axis(0) FROM SalesWHERE ( M

12、easures.Dollar Sales )还可以将逗号和冒号混合使用,如下面的代码如下: Time.2005, Time.January-2006 : Time.March-2006 上面的代码建立一个 2005 年的集合以及 2006 年 1 月至 3 月的集合。.Members获得一个维度、层次的成员集合是非常普遍的一种操作,也是进一步做其他操作的基础。.Members 操作符可以操作一个维度、层次,并返回所有和这些元数据范围的所有成员的集合。如Customer.Members 返回所有的的 Customer 集合,而Product.Product Category.Members 返回

13、所有的成员的产品目录的成员。例子代码如下:当一个客户使用.Members(或是其他可以返回和响应的成员集合的元数据函数),分析服务和 Essbase 都不会包括任何被计算过的成员。在分析服务中还提供了 AddCalculatedMembers()和.AddMembers 函数来向集合中加入成员。.Children另一种使用频率非常高的选择方法就是获得成员的孩子(children)。可以使用下钻的操作,或者是简单地获得一个基于 parent 的成员的范围。MDX 提供了一个.Children函数,这个函数将为实现这个功能。下面的MDX 语句将在rows 上选择Product.Tools的成员和它

14、的 Children,代码如下:可以通过这个函数获得任何一个有 Children 的成员的 Children。如果子节点的孩子,就会得到一个空的集合。使用 Descendants()函数获得成员的子孙获得一个叶为了获得成员的更次的孩子。或是为了进行更深的搜寻,可以使用Descendants()函数。由于这个函数的选择过我,因此,只一下它的基本的用法。Descendants ()方法的语法如下:Descendants (member , level , flag )Descendants()方法返回了和层次或当前的成员的子孙。下面是这个方法的一些选项:SELF BEFORE AFTERSELEC

15、T Time.Q3, 2005.Children on columns, Product.Tools, Product.Tools.Children on rowsFROM SalesWHERE (Customer.TX, Measures.Unit Sales)SELECT Scenario.Members on columns, Store.Members on rows FROM BudgetingWHERE (Customer.Lubbock, TX, Measures.Unit Sales)SELF_AND_BEFORE SELF_AND_AFTER SELF_BEFORE_AFTE

16、R LEAVESSELF 仅仅份。代码如下:SELECT了层的成员,这是最学用的选项。如下面的代码选择了 2007 年的月 Product.Tools, Product.Toys ON COLUMNS, Descendants (Time.2007,Time.Month, SELF)ON ROWSFROM SalesWHERE Measures.Dollar Sales由于 SELF 使用非常频繁,因此,这个选项是默认的。如果在代码中忽略了这个标志。如 Descendants (Time.2007, Time.Month)同样返回 2007 年的月份列表。另外一个选项 SELF_AND_BEF

17、ORE 表示返回 SELF 和“before”层之间的所有成员。如下面的代码挑出了在 2007 年的四个季度和每个月份。代码如下:如何使用 MDX 编写同比和环比在做 BI 项目中,用户会经常提出类似下面这样的需求:本月比上月的销售额增长了多少?百分比是多少?本季度第一个月比上季度第一个月的销售额增长了多少?百分比是多少?其实这两个需求就是常说的同比和环比问题,它们用关系数据库的 SQL 语句难于实现,而用 BI 中的 MDX 来做却轻而易举。以下例子采用的是 SQL Server2005的ysis Servi中的示例库。环比需求:本月比上个月的销售额增长了多少个百分点?MDX 语句如下: P

18、roduct.Tools, Product.Toys ON COLUMNS, Descendants (Time.2007,Time.Month, SELF_AND_BEFORE)ON ROWSFROM SalesWHERE Measures.Dollar Sales结果如下:上面的输出结果有一个问题,就是第一行数据会发生除 0 的情况,为了防止这种情况,MDX:如果发现 0 为空,则显示空字符串。输出结果如下:WITH MEMBER Measures.Amount Change Rate AS IIF(ISEMPTY(Measures.ernet SalesAmount,Date.Fisca

19、l.CurrentMembrevMember), ,Measures.ernet Sales Amount/(Measures.ernet Sales Amount,Date.Fiscal.CurrentMembrevMember)-1), FORMAT_STRING = 0% SELECTMeasures.ernet Sales Amount, Measures.Amount Change Rate ON 0, Date.Fiscal.Month.MembersON 1FROM Adventure WorksWITH MEMBER Measures.Amount Change Rate AS

20、 Measures.ernet Sales Amount/(Measures.ernet Sales Amount,Date.Fiscal.CurrentMembrevMember)-1, FORMAT_STRING = 0% SELECTMeasures.ernet Sales Amount, Measures.Amount Change Rate ON 0, Date.Fiscal.Month.Members ON 1FROM Adventure Works同比需求:本季度每个月比上个季度同期销售额增长了多少个百分点?运行结果如下:和环比相同,这里也出现了除 0 的情况,所以把 MDX 做

21、如下修改:WITH MEMBER Measures.Change Amount Rate AS IIF(Measures.ernet Sales Amount,WITH MEMBER Measures.Change Amount Rate AS Measures.ernet Sales Amount/(Measures.ernet Sales Amount, Cousin(Date.Fiscal.CurrentMember,Date.Fiscal.CurrentMembarent.PrevMember) - 1, FORMAT_STRING = 0%SELECT Measures.ernet

22、Sales Amount, Measures.Change Amount Rate ON 0, Date.Fiscal.Month.Members ON 1FROM Adventure Works输出结果如下:总结同比和环比是 BI 项目中经常要做得内容,采用 MDX 语句可以轻松的实现这个需求。MDX 中一些常见的计算本文来源于MDX Solutions withSQL.Serverysis Servi2005 and Hyperion Essbase 2nd Edition一书的内容,主要介绍了一些经常编写的 MDX 语句的写法。以下 MDX 语句可以在 SSAS 的示例库:Adventu

23、re Works中运行。例子模型以下的 MDX 中用到的 Hierarchy 如下:Cousin(Date.Fiscal.CurrentMember, Date.Fiscal.CurrentMembarent.PrevMember)=0, ,Measures.ernet Sales Amount/(Measures.ernet Sales Amount, Cousin(Date.Fiscal.CurrentMember,Date.Fiscal.CurrentMembarent.PrevMember) - 1), FORMAT_STRING = 0%SELECT Measures.ernet S

24、ales Amount, Measures.Change Amount Rate ON 0, Date.Fiscal.Month.Members ON 1FROM Adventure Works百分比1)某个子项占总体的百分比。比如:每种 Product 的销售额占所有 Product 销售额的百分比。WITH MEMBER Measures.Sale Amount Ratio ASMeasures.ernet Sales Amount/(Measures.ernet Sales Amount,Product.Product Categories.All) , FORMAT_STRING =

25、0.00% SELECTMeasures. 0,ernet Sales Amount, Measures.Sale Amount Ratio ONNON EMPTY Product.Product Categories.Product Name.Members ON 1 FROM Adventure Works2)某个子项占其父项的百分比。比如:每种 Product 的销售额占其所属的SubCategory 销售额的百分比。WITH MEMBER Measures.Sale Amount Ratio ASMeasures.(Measures.ernet Sales Amount/ernet S

26、ales Amount, Product.ProductCategories.CurrentMemb, FORMAT_STRING = 0.00% SELECTarent)Measures. ON 0,ernet Sales Amount, Measures.Sale Amount RatioNON EMPTY CROSSJOIN(Product.Subcategory.Subcategory.Members, Product.Product Categories.Product Name.Members) ON 1FROM Adventure Works3)某个子项占其祖先的百分比。比如:每

27、种 Product 的销售额占其所属的Category 销售额的百分比。WITH MEMBER Measures.Sale Amount Ratio ASMeasures.(Measures.ernet Sales ernet SalesAmount/ Amount,Categories.CurrentMember,ANTOR(Product.ProductProduct.Product Categories.Category), FORMAT_STRING = 0.00% SELECTMeasures. ON 0,ernet Sales Amount, Measures.Sale Amoun

28、t RatioNON EMPTY CROSSJOIN(Product.Category.Category.Members, Product.Product Categories.Product Name.Members) ON 1FROM Adventure Works分配、分摊数量1)根据一个 Measure 值来分配数量。比如:按照每种 Product 占总体的销售额多少来分摊成本。WITH MEMBER Measures.Product Cost AS(Measures.ernet Total Product Cost, Product.ProductCategories.All)*Me

29、asures.ernet Sales Amount/(Measures.ernet Sales Amount, Product.ProductCategories.All), FORMAT_STRING = 0.00 SELECTMeasures.ernet Sales Amount, Measures.Product Cost ON 0,NON EMPTY Product.Product Categories.Product Name.Members ON 1 FROM Adventure Works2)根据一个 Hierarchy 来分配数量。比如:在 Product Hierarchy

30、中计算每种Category 的成本的时候,可以根据每种 Category 下有多少个产品来进行分配。WITH MEMBER Measures.Product Cost AS(Measures.ernet Total Product Cost, Product.ProductCategories.All)/ Count(Descendants (Product.Product Categories.CurrentMember, Product.Product Categories.Product Name, SELF), INCLUDEEMPTY), FORMAT_STRING = 0.00 S

31、ELECTMeasures.ernet Sales Amount, Measures.Product Cost ON 0,NON EMPTY Product.Product Categories.Category.Members ON 1 FROM Adventure Works平均值1)简单平均值。比如:计算一个月中每天平均的销售额是多少。WITH MEMBER Measures.Avg Gross Profit Margin AS Measures.Internet Sales Amount/COUNT(Descendants(Ship Date.Fiscal.CurrentMember,

32、 Ship Date.Fiscal.Date), INCLUDEEMPTY)SELECTMeasures.Internet Sales Amount, Measures.Avg Gross Profit Margin ON COLUMNS,Ship Date.Fiscal.month.Members ON ROWS FROM Adventure Works2)加权平均值。没有想到好的例子。基于时间的计算 1)同比和环比。比如:今年每月的销售额和去年同期相比的变化参见前两天写的 Blog :/microsheen/archive/2006/10/28/542818.html,这里要补充的是,在同

33、比 MDX 中,采用 COUSIN 或ParallelPeriod 都可以,但是采用 ParallelPeriod 更好一些。2)累计到当前的统计。比如:得到一年中每一个月的累计销售额。WITH MEMBER Measures.Additive Internet Sales Amount AS SUM(PeriodsToDate(Ship Date.Fiscal.Fiscal Year,Ship Date.Fiscal.CurrentMember),Measures.Internet Sales Amount)SELECTMeasures.Internet Sales Amount, Meas

34、ures.Additive Internet Sales Amount ON COLUMNS,Ship Date.Fiscal.month.Members ON ROWS FROM Adventure Works3)移动平均值。比如:计算一种 Category 过去三个月的平均销售额合计。WITH MEMBER Measures.Average Internet Sales Amount AS AVG(LastPeriods(3, Date.Calendar.CurrentMember),Measures.Internet Sales Amount)SELECTMeasures.Interne

35、t Sales Amount, Measures.Average Internet Sales Amount ON COLUMNS,NON EMPTY (Product.Product Categories.Category.Members, DESCENDANTS(Date.Calendar.Calendar Year.&2002,Date.Calendar.Month, SELF) ON ROWSFROM Adventure Works在 MDX 中处理边界情况本文来源于MDX Solutions withSQL.Serverysis Servi2005 and Hyperion Essb

36、ase 2nd Edition一书的内容。在编写 MDX 中,各种各样的边界情况存在,比如:Member 不存在,被 0 除,或则某个部分在 cube 和维度中并不存在等等,本文对这些情况下如何来处理做了一个小结。以下 MDX语句可以在 SSAS 的示例库:Adventure Works 中运行。Member 不存在的情况在使用 Member 的一些函数(比如:Lag,LearalledPeriod 等)的时候,经常需要得到当前的 Member 相对的一个 Member(比如:前一个 Member,父级 Member,或去年同期的一个 Member 等等)。然而由于维度和 Hierarchy

37、中的 Member 是有限的,所以这个相对的 Member 有时并不存在。在这种情况下,可以用 IIF 判断这个 Member 是否为 Null 来解决这个问题(z)。比方说,计算过去 6 个月的平均销售额。WITH MEMBER Measures.Last 6 Mon IIF (verage Sales Amount ASDate.Calendar.CurrentMember.Lag(5) IS NULL, NULL,Avg (Date.Calendar.CurrentMember.Lag(5): Date.Calendar.CurrentMember,Measures.ernet Sale

38、s Amount), FORMAT_STRING=Currency SELECTMeasures.ernet Sales Amount, Measures.Last 6 MonverageSales Amount ON 0,Date.Calendar.Month.Members ON 1 FROM Adventure WorksLevel 错误的情况有的时候,Axis 中的 Set 包含了位于不同 Level 的 Member,而且每个 Level 中对于 Member 的处理方式不同,这种情况下的处理也要。比方说,在计算每种产品和其所属 SubCategory,Category 的销售量的时

39、候,对于产品示其标准价格(List Price),可以象下面这样来写。需要显WITH MEMBER Measures.Product List Price AS IIF (Product.Product Categories.CurrentMember.Level IS Product.Product Categories.Product Name,Product.ProductCategories.CurrentMemb NULL) SELECTroperties(List Price),Measures. ON 0,ernet Sales Amount,Measures.Product L

40、ist PriceDESCENDANTS(Product.Product Categories.All, Product.Product Categories.Product Name, SELF_AND_BEFORE ) ON 1FROM Adventure Works被 0 除的情况表达式出现 0 为除数的情况有两种:Member, Cell(也就是 Turple)不存在SSAS 中,如果 Member, Cell 不存在,其返回的值是 0。比如:统计每个月每种产品的销售额时,但是有可能在某个月份某个产品由于没有卖出一个。这种情况下,上文已有说明。Cell 统计的值为 0比如:统计每个月份

41、占所处季度利润百分比的时候,有可能该季度的利润为 0。无论是那种情况,对于被 0 除你可以用判断表达式是否为 0 来处理,像下面这样计算同期比:WITH MEMBER Measures.Same Period Ratio ASIIF(Measures.ernet Sales Amount,ParallelPeriod(Date.Calendar.Calendar Year, 1,Date.Calendar.CurrentMember) = 0, NULL,Measures. (ernet Sales Amount/Measures.ernet Sales Amount,ParallelPeri

42、od(Date.Calendar.Calendar Year, 1,Date.Calendar.CurrentMember) - 1), FORMAT_STRING=Percent SELECTMeasures. ON 0,NONernet Sales Amount, Measures.Same Period RatioEMPTYDESCENDANTS(Date.Calendar.AllPeriods,Date.Calendar.Month, SELF) ON 1 FROM Adventure WorksMDX 的上下文(Context) 面的 Blog 中,说要构建 Cube 或编写 MDX

43、,就必须理解 Cube 的结构。当熟悉了 Cube 结构之后,还是会有很多困挠。比如:为何有些需求用MDX 语句似乎做不出来?为何有些 MDX 语句无法输出想要的结果(不是抱错就是输出结果错误)?为何有些 MDX 语句执行起来非常的慢?要想解决这些问题,除了了解 Cube 结构,还必须理解 MDX 的运行机制,而运行机制的首要概念便是上下文(Context)。以下 MDX 语句可以在SSAS 的示例库:Adventure Works中运行。上下文(Context)MDX 的运行机制可以用一句话来描述在 Cube 结构的基础上,按照一定顺序执行 MDX 中的不同部分,然后根据不同部分的上下文来计

44、算,最后输出。这里有一个问题:何为 MDX 的上下文呢?上下文是指在所有维度的 Hierarchy 上都取一个或多个值的区域。请看下图:上图中的蓝色部分好比整个 Cube,而红域代表了一个上下文。当然实际的Cube 包含多个维度,所以实际的样子会比上图(只有两个维度)复杂得多。这里插一句话,要理解 MDX,最好忘掉 SQL 语句。原因在于:1)SQL 语句中的上下文一般只有一个,如果多个的话,一般执行速度将会变得很慢。而 MDX 语句中一般都包含多个上下文,不同的部分上下文往往不同,执行起来速度很快; 2)在关系型的二维结构中,SQL 语句中的所有的内容都是明确指定的(所有的列和表等),而在

45、MDX 语句中,除了明确指定外,很多内容实际是隐含指定的,这些指定在不同语句中可能会给被传递或改写,这就是 MDX 语句的复杂之处,这也是就是 MDX 和 SQL 的最大区别,这同时也是为什么有些需求只能用 MDX 语句来实现的原因,比如:同比、环比、移动平均、KPI 等。为了加深对上下文的认识,让每天的销售额。来看一看下面的语句计算每种产品的平均上面这段 MDX 语句能够正常的计算出结果,但是,如果计算每种产品在 2002 年和 2003 年的平均每天的销售额。加上一些限定,比如:上面的 MDX 语句的输出结果中会出现很多#error,其原因在于:在Measures.Averageernet

46、 Sales Amount的当前上下文中,由于Date.Calendar仅包含两个成员(即 2002 年和 2003 年),所以 MDX器无法确定哪一个成员是 CurrentMember。要想解决这个问题,其中的一个办法是使用 Existing,详见下文:WITH MEMBER Measures.Averageernet Sales Amount AS AVG(DESCENDANTS(Date.Calendar.CurrentMember, Date.Calendar.Date,SELF), Measures.ernet Sales Amount)SELECTMeasures.ernet Sa

47、les Amount,Measures.Averageernet Sales Amount ON 0,NON EMPTY Product.Product Categories.Product Name.Members ON 1 FROM Adventure WorksWHEREDate.Calendar.Calendar Year.&2002, Date.Calendar.Calendar Year.&2003WITH MEMBER Measures.Averageernet Sales Amount AS AVG(DESCENDANTS(Date.Calendar.CurrentMember

48、, Date.Calendar.Date,SELF), Measures.ernet Sales Amount)SELECTMeasures.ernet Sales Amount,Measures.Averageernet Sales Amount ON 0,NON EMPTY Product.Product Categories.Product Name.Members ON 1FROM Adventure Works上面的语句中 EXISTING Date.Calendar.Date表示当前上下文中包含的 Date.Calendar.Date,所以能够得到正确的结果。总结本文简单介绍了 M

49、DX 的运行机制中的上下文的概念,它是理解 MDX 的关键概念之一。要深入一些的话 有的朋友MoshaWhere vs. Subselect/SubcubeWhere 和 Subselect/Subcube 在 MDX 都是经常使用的语句,有的时候它们能起到相同的效果,而有的时候却又不能,这究竟是什么原因呢?本文将尝试就这些情况作一些分析(不对之处,欢迎大家及时 )。以下 MDX 语句可以在 SSAS(打了 SP2 补丁的版本)的示例库:Adventure Works 中运行。相同和不同Where 和 Subselect/Subcube 都能够限定计算的范围。请看下面的两个语句:例一SELEC

50、TMeasures.ernet Sales AmountON 0, Date.Calendar.Calendar Year.Members ON 1FROM Adventure WorksWHEREProduct.Product Categories.Category.Bikes SELECTMeasures.ernet Sales Amount ON 0, Date.Calendar.Calendar Year.Members ON 1 FROM(SELECT Product.Product Categories.Category.Bikes ON 0 FROM Adventure Work

51、s)WITH MEMBER Measures.Averageernet Sales Amount AS AVG(EXISTING Date.Calendar.Date,Measures.ernet Sales Amount) SELECTMeasures.ernet Sales Amount,Measures.Averageernet Sales Amount ON 0,NON EMPTY Product.Product Categories.Product Name.Members ON 1 FROM Adventure WorksWHEREDate.Calendar.Calendar Ye

52、ar.&2002, Date.Calendar.CalendarYear.&2003以上两条语句能够返回相同的计算结果(见下图),这个结果中仅仅包括 Bikes的销售金额。但是,Where 和 Subselect/Subcube 也有不同。请看下面的两个语句:例二它们的结果分别如下所见:WITHMEMBER Measures.Category Name ASProduct.Product Categories.CurrentMember.MemberValueSELECTMeasures.Category NameON 0,Date.Calendar.Calendar Year.Members

53、 ON 1FROM Adventure WorksWHEREProduct.Product Categories.Category.Bikes WITHMEMBER Measures.Category Name ASProduct.Product Categories.CurrentMember.MemberValue SELECTMeasures.Category NameON 0, Date.Calendar.Calendar Year.Members ON 1 FROM(SELECTProduct.Product Categories.Category.Bikes ON 0FROM Ad

54、venture Works)从上面的结果可以看出,Where 语句的改变了Product.ProductCategories的当前 Member,而 Subselect/Subcube 语句没有。另外再看一种不同的情况:例三WITHMEMBER Measures.Test1 AS AGGREGATE(EXISTING Product.ProductCategories.Subcategory.Members,Measures.ernet Sales Amount)MEMBER Measures.Test2 AS AGGREGATE(Product.ProductCategories.Subca

55、tegory.Members,Measures.ernet Sales Amount)SELECTMeasures.Test1, Measures.Test2 ON 0, Date.Calendar Year.MEMBERS ON 1FROM Adventure Works WHEREProduct.Product Categories.Subcategory.Socks, Product.Product Categories.Subcategory.Road Bikes WITHMEMBER Measures.Test1 AS AGGREGATE(EXISTING Product.Produ

56、ctCategories.Subcategory.Members,Measures.ernet Sales Amount)MEMBER Measures.Test2 AS AGGREGATE(Product.ProductCategories.Subcategory.Members,Measures.ernet Sales Amount)SELECTMeasures.Test1, Measures.Test2 ON 0, Date.Calendar Year.MEMBERS ON 1FROM (SELECTProduct.Product Categories.Subcategory.Socks

57、, Product.Product Categories.Subcategory.Road Bikes on 0它们的结果分别如下:上面的结果中, Measures.Test1 代表当前 Context 的销售数量,而Measures.Test2代表了总的销售数量,知道 Existing 函数强制指定的Set在当前的Context下进行计算( HYPERLINK http:/m/ http:/m/en-us/library/ms145541.aspx),Where 情况下,使用 Existing 的Measures.Test1一切正常,而 Subselect/Subcube 情况下,使用 Ex

58、isting 的Measures.Test1似乎没有发生任何作用,这是什么原因呢?分析以上的结果,无论是相同还是不同,都和 Context 有关系。知道:每一个 Set,Member,Turple 都执行在一个特定的 Context 中。 Subselect/Subcube 设定了整个 Cube 的 Context,而 Where 和所有 Axis 一起构成了 Calculate Member 当前 Context。这些设定都影响了计算时的数据范围,这就是第一个例子中为何 Subselect/Subcube 和 Where 返回相同结果的原因。接下来的例子中,Where 情况下,能够返回希望的

59、当前 Member 的原因在于:Where也是一个 Axis,即常说的 Silcer Axis,它和所有 Axis 设定了各个 Attribute Hierarchy 的当前的 Member,而 Subselect/Subcube 对 Attribute Hierarchy当前的 Member 没有做任何的改变。对于第三个例子,在 Subselect/Subcube 情况使用 Existing 函数无效,说明Subselect/Subcube 对当前的Context 并无影响,这同时说明Subselect/Subcube和Where的Context 并不完全相同,在不同情况下,可能采用不同的上

60、下文。Existing 失效并不妨碍 Subselect/Subcube 在计算时对数据范围的影响,这说明在作 Cell 计算(包括 Calculate Member)的时候,Subselect/Subcube 和 Where的 Context 都会同时被采用(除了 Context 被替换的情况,就像第三个例子中的FROM Adventure Works)Measures.Test2中Product.ProductCategories.Subcategory.Members 替换了当前 Context 和 Cube Context 中Product维度的当前设置一样)。总结Where 和 Su

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论