代码改变世界

MDX Step by Step 读书笔记(五) - Working with Expressions (MDX 表达式)

2013-04-18 18:19  BIWORK  阅读(2074)  评论(1编辑  收藏  举报

1. 大多数表达式会返回数值类型的值,但是也能返回例如字符串,时间,布尔或者其它类型的值。

2. 一般表达式的结果都是几个值通过操作符运算后得到的,下列表格中显示了对比,逻辑的,数值的,字符串以及集合操作符。

3. SSAS 中的 VBA 函数

 

4. Calculated Members 计算成员

可以把计算成员当成已存在的属性或者层次结构的一个成员,但是计算成员又和其它的传统成员不同,它并不会把值保存在 Cube空间里。

WITH
MEMBER [Product].[Category].[All Products].[X] AS
1+1
SELECT
{
    ([Date].[Calendar Year].[CY 2003]),
    ([Date].[Calendar Year].[CY 2004])
} ON COLUMNS,
{
    ([Product].[Category].[Accessories]) ,
    ([Product].[Category].[Bikes]),
    ([Product].[Category].[Clothing]),
    ([Product].[Category].[Components]),
    ([Product].[Category].[X])
} ON ROWS
FROM [Step-by-Step];

这是一个计算成员的示例,在Cube 中的任何成员都必须依附于某一个层次结构,可以是纬度层次结构也可以是度量值层次结构。

这个例子中,计算成员 X 被定义为 Product 纬度 Category 属性层次结构中的一个成员,表达式 1+1 赋予给这个计算成员,结果为2。

但是要注意,如果使用 Members 函数,那么某个纬度下的计算成员将不会出现:

WITH
MEMBER [Product].[Category].[All Products].[X] AS
1+1
SELECT
{
    ([Date].[Calendar Year].[CY 2003]),
    ([Date].[Calendar Year].[CY 2004])
} ON COLUMNS,
{[Product].[Category].[Category].Members} ON ROWS
FROM [Step-by-Step]

这时就要使用 ALLMembers 函数来同时显示成员和计算成员。

WITH
MEMBER [Product].[Category].[All Products].[X] AS
1+1
SELECT
{
    ([Date].[Calendar Year].[CY 2003]),
    ([Date].[Calendar Year].[CY 2004])
} ON COLUMNS,
{[Product].[Category].[Category].AllMembers} ON ROWS
FROM [Step-by-Step]

另外,现在看到的计算成员的使用范围还是属于当前查询范围的,只能在当前查询语句中使用。

动态表达式

示例一

在 Product 纬度下层次结构中添加一个新的计算成员,这个计算成员由一个元组和一个常量相加形成一个表达式。

WITH
MEMBER [Product].[Category].[All Products].[X] AS
([Product].[Category].[Bikes])+1
SELECT
{
            ([Date].[Calendar Year].[CY 2003]),
            ([Date].[Calendar Year].[CY 2004])
} ON COLUMNS,
{[Product].[Category].AllMembers} ON ROWS
FROM [Step-by-Step];

X 的值是 Bikes 在 2003 和 2004年的值+1。

示例二

还是在 Product 纬度下的层次结构中添加一个新的成员Bikes & Accessories, 在它的表达式中由两个 Category 的成员相加组成,即两个元组参与了相加的运算。这个两个元组一个是引用了 Bikes 这个成员,另一个是引用了 Accessories 这个成员。

WITH
MEMBER [Product].[Category].[All Products].[Bikes & Accessories] AS
([Product].[Category].[Bikes]) + ([Product].[Category].[Accessories])
SELECT
{
    ([Date].[Calendar Year].[CY 2003]),
    ([Date].[Calendar Year].[CY 2004])
} ON COLUMNS,
{[Product].[Category].AllMembers} ON ROWS
FROM [Step-by-Step]

查询的结果可以看到 Bikes & Accessories 在2003年和2004年的值等于 Bikes 和 Accessories在2003年和2004年相加的结果。

下面分析一下 SSAS 是如何解析这个计算成员的,并且是如何动态赋值的。

由于我们已经定义了这个计算成员成为 Category 属性层次结构中的一个成员,那么在使用{[Product].[Category].AllMembers 时就能够访问到这个计算成员。我们考虑一下比如 [Date].[Calendar Year].[CY 2003] 成员 和 [Product].[Category].[All Products].[Bikes & Accessories] 这个成员形成的一个交叉点,实际上就是一个单元格或者也可以理解为一个局部元组 –

([Date].[Calendar Year].[CY 2003], [Product].[Category].[All Products].[Bikes & Accessories])  SSAS 会按照3个填充局部元组的规则对这个元组进行填充。(需要了解填充局部元组规则的请参看第三章学习笔记)

 

填充这个局部元组的过程参照上图,最终会得到一个完整的元组 (假设当前环境下只有这几个纬度和层次结构的情况下)。

(
    [Date].[Calendar Year].[CY 2003],
    [Date].[Fiscal Year].[All Periods],
    [Product].[Category].[Bikes & Accessories],
    [Product].[Subcategory].[All Products],
    [Measures].[Reseller Sales Amount]        
)

但是这个完整的元组包含了一个计算成员 [Product].[Category].[Bikes & Accessories] 因此在实际的Cube 空间里是找不到和它对应的一个点或者一个实际存储有值的那个单元格。那么这时 SSAS 就需要应用表达式获取它的值。

由于这个表达式包含了两个局部元组

([Product].[Category].[Bikes]) 和 ([Product].[Category].[Accessories]),为了补充这两个局部元组,SSAS 不再像之前一样按照规则进行补充,而是从当前的那个已经完成的元组中直接去引用其它成员来实现一个完整的元组。换一个角度来说,当前这个完整的元组为计算成员中出现的元组提供了上下文环境,供其直接引用当前环境的其它成员。

有一点非常重要就是,这两个局部元组只会引用自己所没有的层次结构的其它成员,因此在填充它们自己的元组时因为 [Product].[Category].[Bikes & Accessories]和他们同属一个层次结构,他们已经同在一个轴上,因此将不会再去引用。

对于局部元组 ([Product].[Category].[Bikes]) 而言,对它进行填充的后得到一个完整的元组可以在空间上具体定位到一个点。

(
    [Date].[Calendar Year].[CY 2003],
    [Date].[Fiscal Year].[All Periods],
    [Product].[Category].[Bikes],
    [Product].[Subcategory].[All Products],
    [Measures].[Reseller Sales Amount]        
)

对于局部元组 ([Product].[Category].[ Accessories]) 而言,对它进行填充的后得到一个完整的元组可以在空间上具体定位到一个点。

(
    [Date].[Calendar Year].[CY 2003],
    [Date].[Fiscal Year].[All Periods],
    [Product].[Category].[ Accessories] ,
    [Product].[Subcategory].[All Products],
    [Measures].[Reseller Sales Amount]        
)

这样两个完整的元组所表示的值通过操作符 + 相加,就能得到一个结果,这个结果就是计算成员的结果。

因此像这样把 CY 2003 改称 CY 2002

(
    [Date].[Calendar Year].[CY 2002],
    [Date].[Fiscal Year].[All Periods],
    [Product].[Category].[Bikes & Accessories],
    [Product].[Subcategory].[All Products],
    [Measures].[Reseller Sales Amount]        
)

那么 SSAS 在解析它时实际上也就变成了这两个值相加的结果

(
    [Date].[Calendar Year].[CY 2002],
    [Date].[Fiscal Year].[All Periods],
    [Product].[Category].[Bikes],
    [Product].[Subcategory].[All Products],
    [Measures].[Reseller Sales Amount]        
)
+
(
    [Date].[Calendar Year].[CY 2003],
    [Date].[Fiscal Year].[All Periods],
    [Product].[Category].[ Accessories],
    [Product].[Subcategory].[All Products],
    [Measures].[Reseller Sales Amount]        
)

以上就是我对动态表达式解析的原理分析。

更多 BI 文章请参看 BI 系列随笔列表 (SSIS, SSRS, SSAS, MDX, SQL Server)  如果觉得这篇文章看了对您有帮助,请帮助推荐,以方便他人在 BIWORK 博客推荐栏中快速看到这些文章。