MDX Step by Step 读书笔记(五) - Working with Expressions (MDX 表达式) - CurrentMember - Properties - Existing 的使用
2013-04-19 15:48 BIWORK 阅读(5238) 评论(5) 编辑 收藏 举报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 的作用。
更多 BI 文章请参看 BI 系列随笔列表 (SSIS, SSRS, SSAS, MDX, SQL Server) 如果觉得这篇文章看了对您有帮助,请帮助推荐,以方便他人在 BIWORK 博客推荐栏中快速看到这些文章。