MDX Step by Step 读书笔记(五) - Working with Expressions (MDX 表达式) - CurrentMember - Properties - Existing 的使用

浏览: 2720

Current Member  当前成员

在计算成员中会经常用到获取当前对象的函数, 可以这样来访问 [Dimension].[Hierarchy].CurrentMember

但是要注意这个函数返回的仅仅是一个成员的引用,一般要通过访问成员的某些属性来获取一些具体的值。

    

示例一 - 访问当前成员和父成员

WITH
MEMBER [Measures].[Current Member Name] AS
[Product].[Product Categories].CurrentMember.Name

MEMBER [Measures].[Parent Member Name] AS
[Product].[Product Categories].CurrentMember.Parent.Name

MEMBER [Measures].[Current Member Name NULL] AS
[Product].[Product Categories].CurrentMember

MEMBER [Measures].[Parent Member Name NULL] AS
[Product].[Product Categories].CurrentMember.Parent

SELECT
{
([Measures].[Current Member Name]),
([Measures].[Parent Member Name]),
([Measures].[Current Member Name NULL]),
([Measures].[Parent Member Name NULL])
} ON COLUMNS,
{[Product].[Product Categories].AllMembers} ON ROWS
FROM [Step-by-Step]

查询结果

最后两列的值都是为 NULL, 是因为无论是 CurrentMember 还是 CurrentMember.Parent 返回的只是一个引用,要得到具体的值就应该在引用的时候加上一些属性。

CurrentMember 返回的是当前的成员

CurrentMember.Parent 返回的是当前成员的父成员引用

在这个例子中可以看到这些成员的父成员,除了 All Products 外,因为对于 All Products 来说它没有父成员,所以显示为 null。

MEMBER.Properties 函数的使用

Properties 可以帮助通过名称返回一个成员固有的或者用户自定义的属性内容。一般情况下是以字符串形式返回,除了指定了 TYPED 关键字,那么将按照这个属性本身的数据类型来返回数据。

member.Properties( Name [, TYPED] )

下面列表中列出了 SSAS 自带的成员属性 

示例二 使用 Properties

WITH
MEMBER [Measures].[Parent Member Name] AS
[Product].[Product Categories].CurrentMember.Properties("LEVEL_NUMBER")

SELECT
{([Measures].[Parent Member Name])} ON COLUMNS,
{[Product].[Product Categories].AllMembers} ON ROWS
FROM [Step-by-Step];

按照之前的图例解释 LEVEL_NUMBER 返回的是这个成员在属性层次结构中的位置,根成员的Level 为0。

查询结果 –

示例三  使用 IIF 条件语句

使用IIF 表达式很简单,和我们在其它变成语言中学习的 if 条件语句使用相同

下面示例查询所有的 Product 成员并显示它们的父成员,由于根Level的成员没有父成员,因此根成员的父成员将被显示为 “Not Applicable”

WITH
MEMBER [Measures].[Parent Member Name] AS
IIF(
[Product].[Product Categories].CurrentMember.Properties("Level_Number",TYPED)=0,
"Not Applicable",
[Product].[Product Categories].CurrentMember.Parent.Name
)

SELECT
{([Measures].[Parent Member Name])} ON COLUMNS,
{[Product].[Product Categories].AllMembers} ON ROWS
FROM [Step-by-Step];

查询结果

示例四 继续使用 IIF 条件 

WITH
MEMBER [Measures].[Parent Member Name] AS
IIF(
[Product].[Product Categories].CurrentMember.Properties("Level_Number",TYPED)=0,
   "Not Applicable",
   [Product].[Product Categories].CurrentMember.Parent.Name
)

MEMBER [Measures].[Percent of Parent] AS
  ([Measures].[Reseller Sales Amount])/
  ([Product].[Product Categories].CurrentMember.Parent, [Measures].[Reseller Sales Amount])
  ,FORMAT_STRING="Percent"

SELECT
{
([Measures].[Parent Member Name]),
([Measures].[Reseller Sales Amount]),
([Measures].[Percent of Parent])
} ON COLUMNS,
{[Product].[Product Categories].AllMembers} ON ROWS
FROM [Step-by-Step];

第一点要注意的是如何引用一个父类成员 [Product].[Product Categories].CurrentMember.Parent

而不是之前的例子中[Product].[Product Categories].CurrentMember.Parent.Name, 请一定分清父成员和父成员属性的区别。

第二点当父成员为 NULL 的时候,整个元组 ([Product].[Product Categories].CurrentMember.Parent, [Measures].[Reseller Sales Amount])也为NULL,但是在除法运算中将被替换为0 ,分母为0,运算出错。但是注意,这里的 NULL 分为两种情况,一种是真正的NULL,不存在这个值转换为0;一种是因为没有值显示为NULL,那么最后计算的结果也显示为 NULL。

加上对父成员级别的判断

WITH
MEMBER [Measures].[Parent Member Name] AS
IIF(
[Product].[Product Categories].CurrentMember.Properties("Level_Number",TYPED)=0,
"Not Applicable",
[Product].[Product Categories].CurrentMember.Parent.Name
)

MEMBER [Measures].[Percent of Parent] AS
IIF(
[Product].[Product Categories].CurrentMember.Properties("Level_Number",TYPED)=0,
"Not Applicable",
([Measures].[Reseller Sales Amount])/
([Product].[Product Categories].CurrentMember.Parent,
[Measures].[Reseller Sales Amount])
)
,FORMAT_STRING="Percent"

SELECT
{
([Measures].[Parent Member Name]),
([Measures].[Reseller Sales Amount]),
([Measures].[Percent of Parent])
} ON COLUMNS,
{[Product].[Product Categories].AllMembers} ON ROWS
FROM [Step-by-Step]

查询结果

除了 CurrentMember 以外,Analysis Services 还支持其它的一些行数来访问一些比较特别的成员。

[Dimension].[Hierarchy].DefaultMember

[Dimension].[Hierarchy].UnknownMember

[Dimension].[Hierarchy].DataMember

DefaultMember 函数返回一个给定层次结构的默认成员。如果没有定义默认成员,那么就返回All这个成员,如果没有All这个成员,就返回层次结构中第一个成员。

UnknownMember 函数返回指定的层次结构中未知的成员。如果不存在这种 unknown 成员,那么就返回 null。但是在度量值层次结构中使用 UnknownMember,就返回一个 error,因为在度量值层次结构中不应该存在 unknown 成员这种概念。 

DataMember 返回系统生成的数据成员,它与某个维度的非叶成员相关联。

在表达式中使用 SET 集合

在表达式中使用 SET 集合要注意,SET 集合不会被当前单元格的上下文所影响。这样一来,Auto-Exists 机制就无法应用,先来看一个例子。

WITH
MEMBER [Measures].[Number of Products] AS
COUNT(
[Product].[Product].[Product].Members
)

SELECT
{
([Measures].[Reseller Sales Amount]),
([Measures].[Number of Products])
} ON COLUMNS,
{[Product].[Category].Members} ON ROWS
FROM [Step-by-Step]

查询结果

 

按照我们之前的理解, 在计算 Category 下面有多少个Products时,Auto-Exists 会自动归类匹配,但是实际上 Products 集合在计算成员总数的时候并没有关联到计算成员中的Tuple的上下文环境,因此算出来的总数就是实际所有 Product的总数 397。

使用 Existing 关键字可以强制在计算成员表达式中的 SET 使用当前上下文环境。

WITH
MEMBER [Measures].[Number of Products] AS
COUNT(
EXISTING [Product].[Product].[Product].Members
)

SELECT
{
([Measures].[Reseller Sales Amount]),
([Measures].[Number of Products])
} ON COLUMNS,
{[Product].[Category].Members} ON ROWS
FROM [Step-by-Step];

复制代码

可以这样理解,在依次与 Product.Category 层次结构下的各个成员交汇的时候,那么这些成员就限定了计算成员中 Products 统计成员个数的空间。

比如说,当前读取的 Category 成员是Bikes,那么在应用了 Existing 关键字后,可以认为所有的关于 Products 下的 Members 的统计实际上都限定在了 Bikes 这个大类下面来进行了,Bikes 就是它们的上下文环境,其实这就是 Auto-Exists 的作用。

推荐 1
本文由 BIWORK 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册