MDX : Non Empty 和 NonEmpty

原文地址:http://beyondrelational.com/blogs/jason/archive/2010/05/07/mdx-non-empty-v-s-nonempty.aspx

省略若干字....

我最喜欢的 MDX问题是Empty 和Non Empty 的区别,因为尽管很多人平时都用它们来去除查询结果中的 Nulls 值,但是只有少数人理解它们的含义。 好多次我都得到类似 “Non Empty之间有空格,而 NonEmpty 没有”这样的答案。本文的目的在于澄清两者之间的区别。

假设初始的查询是:

SELECT  
  { 
    [Measures].[Hits] 
   ,[Measures].[Subscribers] 
   ,[Measures].[Spam] 
  } ON COLUMNS 
,{ 
    [Geography].[Country].Children 
  } ON ROWS 
FROM [Blog Statistics];

结果如下:

NON EMPTY

Non Empty 是定义为轴的集合的前缀, 用于去除 Nulls, 让我们看看在Rows 轴使用了Non empty 后会发生什么。

SELECT  
  { 
    [Measures].[Hits] 
   ,[Measures].[Subscribers] 
   ,[Measures].[Spam] 
  } ON COLUMNS 
,NON EMPTY  
    { 
      [Geography].[Country].Children 
    } ON ROWS 
FROM [Blog Statistics];

结果如下:


正如你所看到的Chile(CL)已经被过滤了,而UK,Canada等仍然在,即使它们的某些度量也有Nulls。简言之,只有集合定义的行中的所有列成员都为Nulls的行被过滤。这是因为Non Empty 操作符在查询的最高级起作用。 在内部,作为轴定义的集合最先被生成,然后是有Null值的元组被移除。现在我们知道了 Non Empty 是如何工作的,那么说出下面查询的结果也不是什么难事。

SELECT  
  NON EMPTY  
    { 
      [Measures].[Hits] 
     ,[Measures].[Subscribers] 
     ,[Measures].[Spam] 
    } ON COLUMNS 
,{ 
    [Geography].[Country].Children 
  } ON ROWS 
FROM [Blog Statistics];

结果如下:

 

NONEMPTY()

NonEmpty 返回指定集合中的非空元组的集合, 基于特定集合和另一个集合的交集。假设我们想看到所有与国家相关的有人订阅的度量。

SELECT  
  { 
    [Measures].[Hits] 
   ,[Measures].[Subscribers] 
   ,[Measures].[Spam] 
  } ON COLUMNS 
,{ 
    NonEmpty 
    ( 
      [Geography].[Country].Children 
     ,[Measures].[Subscribers] 
    ) 
  } ON ROWS 
FROM [Blog Statistics];

结果如下:

 

正如你所看到的, NonEmpty 操作符返回所有行中无null值的订阅者,并且在列中显示所有度量值。NonEmpty 的值是在集合定义该轴时指定的,在这个时候并没有牵扯其它轴,下面的例子可能更好理解。


查询如下:

SELECT  
  {[Date].[Month].[March]} ON COLUMNS 
,{ 
    [Geography].[Country].Children 
  } ON ROWS 
FROM [Blog Statistics] 
WHERE  
  [Measures].[Hits];

结果如下:

 

稍微想一下猜一下如果NonEmpty 应用在行上结果是什么样的。

SELECT  
  {[Date].[Month].[March]} ON COLUMNS 
,{ 
    NonEmpty([Geography].[Country].Children
  } ON ROWS 
FROM [Blog Statistics] 
WHERE  
  [Measures].[Hits];

如果你觉得只显示 IN, US, GB 和 AU, 请回去再读一遍,如果你回答除了Chile外所有行都出现你就是满分,你是个细心的阅读者。原因是NonEmpty 是在集合定义轴的时候确定的,这里的轴是Country,在确定轴的时候,NonEmpty 是基于Date的默认成员(All)为Country的每一个成员评价出来的,CA和AP已经在其它月有数据了,因此CA和AP仍会出现。

使用NonEmpty优化Non Empty 

现在你已经知道Non Empty 和 NonEmpty 内部是怎么工作的,我们可以使用这些知识优化查询。假设周中有个复杂的逻辑比如说查找每个月点击量都超过30的所有国家。

查询如下:

SELECT  
  {[Measures].[Hits]} ON COLUMNS 
,{ 
    Filter 
    ( 
        [Geography].[Country].Children 
      *  
        [Date].[Month].Children 
     , 
      [Measures].[Hits] > 30 
    ) 
  } ON ROWS 
FROM [Blog Statistics];

在我的维度中有10年的数据,也就是大约120个月属性成员,Country 属性有100个成员。即使我只有10个国家3个月的点击数据,这个条件函数会需要遍历所有国家和月的组合(120* 100). 这样,我们只能用如下查询使用NonEmpty操作符把组合数以减少到30(10*3)以下

SELECT  
  {[Measures].[Hits]} ON COLUMNS 
,{ 
    Filter 
    ( 
      NonEmpty 
      ( 
          [Geography].[Country].Children 
        *  
          [Date].[Month].Children 
       ,[Measures].[Hits] 
      ) 
     , 
      [Measures].[Hits] > 30 
    ) 
  } ON ROWS 
FROM [Blog Statistics];

posted on 2011-03-08 12:10  黑头  阅读(1515)  评论(0编辑  收藏  举报

导航