Where和Subselect/Subcube在MDX都是经常使用的语句,有的时候它们能起到相同的效果,而有的时候却又不能,这究竟是什么原因呢?本文将尝试就这些情况作一些分析(不对之处,欢迎大家及时指出)。以下MDX语句可以在SSAS(打了SP2补丁的版本)的示例库:Adventure Works中运行。

相同和不同
Where和Subselect/Subcube都能够限定计算的范围。请看下面的两个语句:
例一
SELECT
[Measures].[Internet Sales Amount]  ON 0,
[Date].[Calendar].[Calendar Year].Members ON 1
FROM [Adventure Works]
WHERE
[Product].[Product Categories].[Category].[Bikes]
SELECT
[Measures].[Internet Sales Amount] ON 0,
[Date].[Calendar].[Calendar Year].Members ON 1
FROM
(
    
SELECT [Product].[Product Categories].[Category].[Bikes] ON 0
    
FROM [Adventure Works]
)

以上两条语句能够返回相同的计算结果(见下图),这个结果中仅仅包括Bikes的销售金额。

但是,Where和Subselect/Subcube也有不同。请看下面的两个语句:
例二
WITH
MEMBER 
[Measures].[Category Name] AS
[Product].[Product Categories].CurrentMember.MemberValue
SELECT
[Measures].[Category Name]  ON 0,
[Date].[Calendar].[Calendar Year].Members ON 1
FROM [Adventure Works]
WHERE
{
    
[Product].[Product Categories].[Category].[Bikes]
}
WITH
MEMBER 
[Measures].[Category Name] AS
[Product].[Product Categories].CurrentMember.MemberValue
SELECT
[Measures].[Category Name]  ON 0,
[Date].[Calendar].[Calendar Year].Members ON 1
FROM
(
    
SELECT
    {
        
[Product].[Product Categories].[Category].[Bikes]
    } 
ON 0
    
FROM [Adventure Works]
)

它们的结果分别如下所见:


从上面的结果我们可以看出,Where语句的改变了[Product].[Product Categories]的当前Member,而Subselect/Subcube语句没有。

另外再看一种不同的情况:
例三
WITH
MEMBER 
[Measures].[Test1] AS
AGGREGATE(EXISTING 
[Product].[Product Categories].[Subcategory].Members,[Measures].[Internet Sales Amount])
MEMBER 
[Measures].[Test2] AS
AGGREGATE(
[Product].[Product Categories].[Subcategory].Members,[Measures].[Internet Sales Amount])
SELECT 
{
[Measures].[Test1][Measures].[Test2]ON 0,
[Date].[Calendar Year].MEMBERS ON 1
FROM [Adventure Works]
WHERE 
{
    
[Product].[Product Categories].[Subcategory].[Socks],
    
[Product].[Product Categories].[Subcategory].[Road Bikes]
}
WITH
MEMBER 
[Measures].[Test1] AS
AGGREGATE(EXISTING 
[Product].[Product Categories].[Subcategory].Members,[Measures].[Internet Sales Amount])
MEMBER 
[Measures].[Test2] AS
AGGREGATE(
[Product].[Product Categories].[Subcategory].Members,[Measures].[Internet Sales Amount])
SELECT 
{
[Measures].[Test1][Measures].[Test2]ON 0,
[Date].[Calendar Year].MEMBERS ON 1
FROM
(
    
SELECT
    {
        
[Product].[Product Categories].[Subcategory].[Socks],
        
[Product].[Product Categories].[Subcategory].[Road Bikes]
    } 
on 0
    
FROM [Adventure Works]
)
它们的结果分别如下:


上面的结果中,[Measures].[Test1]代表当前Context的销售数量,而[Measures].[Test2]代表了总的销售数量,我们知道Existing函数强制指定的Set在当前的Context下进行计算(http://msdn2.microsoft.com/en-us/library/ms145541.aspx),Where情况下,使用Existing的[Measures].[Test1]一切正常,而Subselect/Subcube情况下,使用Existing的[Measures].[Test1]似乎没有发生任何作用,这是什么原因呢?

分析
以上的结果,无论是相同还是不同,都和Context有关系。

我们知道:每一个Set,Member,Turple都执行在一个特定的Context中。Subselect/Subcube设定了整个Cube的Context,而Where和所有Axis一起构成了Calculate Member当前Context。这些设定都影响了计算时的数据范围,这就是第一个例子中为何Subselect/Subcube和Where返回相同结果的原因。

接下来的例子中,Where情况下,能够返回希望的当前Member的原因在于:Where也是一个Axis,即常说的Silcer Axis,它和所有Axis设定了各个Attribute Hierarchy的当前的Member,而Subselect/Subcube对Attribute Hierarchy当前的Member没有做任何的改变。

对于第三个例子,在Subselect/Subcube情况使用Existing函数无效,说明Subselect/Subcube对当前的Context并无影响,这同时说明Subselect/Subcube和Where构成的Context并不完全相同,在不同情况下,可能采用不同的上下文。Existing失效并不妨碍Subselect/Subcube在计算时对数据范围的影响,这说明在作Cell计算(包括Calculate Member)的时候,Subselect/Subcube和Where的Context都会同时被采用(除了Context被替换的情况,就像第三个例子中的[Measures].[Test2][Product].[Product Categories].[Subcategory].Members替换了当前Context和Cube Context中[Product]维度的当前设置一样)。

总结
Where和Subselect/Subcube都能够限定计算的范围,它们的最大不同在于,Where和所有Axis一起还设置了各个Attribute Hierarchy的当前Member。