Filtering Sets
部分定义参照 MSDN-
Filter 函数对指定集中的每个元组计算指定的逻辑表达式,如果逻辑表达式计算结果为 true,那么该函数将返回由指定集中的每个元组构成的集。如果所有元组的计算结果都不为 true,则返回一个空集。
Filter 函数的工作方式与 IIf 函数类似,IIf 函数只返回两个选项中的一个,返回哪一个取决于 MDX 逻辑表达式的值; 而 Filter 函数返回符合指定搜索条件的元组集。实际上,Filter 函数是对集中的每个元组执行 IIf(Logical_Expression, Set_Expression.Current, NULL),然后返回所得到的集。
示例一 – 查询所有产品的零售额和网售额
SELECT { ([Measures].[Reseller Sales Amount]), ([Measures].[Internet Sales Amount]) } ON COLUMNS, {[Product].[Product].[Product].Members} ON ROWS FROM [Step-by-Step];
示例二 – 查询所有网售额大于零售额的产品
SELECT { ([Measures].[Reseller Sales Amount]), ([Measures].[Internet Sales Amount]) } ON COLUMNS, FILTER( {[Product].[Product].[Product].Members}, [Measures].[Internet Sales Amount] > [Measures].[Reseller Sales Amount] ) ON ROWS FROM [Step-by-Step];
上面的查询结果显示的是所有的产品,那么如果只想关心 accessory 和 clothing 子类产品的话,那么就需要修改条件表达式。
示例三 – 在 accessory 和 clothing 范围下查询所有 Internet Sales Amount 大于 Reseller Sales Amount 的产品
SELECT { ([Measures].[Reseller Sales Amount]), ([Measures].[Internet Sales Amount]) } ON COLUMNS, FILTER( {[Product].[Product].[Product].Members}, ([Measures].[Internet Sales Amount] > [Measures].[Reseller Sales Amount]) AND ( [Product].[Category].CurrentMember IS [Product].[Category].[Clothing] OR [Product].[Category].CurrentMember IS [Product].[Category].[Accessories] ) ) ON ROWS FROM [Step-by-Step];
在这个查询中,很显然 Auto-Exists 又起了作用。在 Filter 函数中实际上查询的是 {[Product].[Product].[Product].Members} 中的产品成员,但是在条件表达式上能够直接对[Product].[Category].CurrentMember 进行判断,通过产品成员可以定位到产品成员所隶属的产品分类成员,这就是 Auto-Exists 的作用。
示例四 – 查询不在 accessory 和 clothing 范围下查询所有 Internet Sales Amount 大于 Reseller Sales Amount 的产品
只需要对示例三中的代码做出小小的改动,加一个NOT 关键字 就构成了”既不在 Clothing 也不在 Accessories 类别下”的筛选条件。
SELECT { ([Measures].[Reseller Sales Amount]), ([Measures].[Internet Sales Amount]) } ON COLUMNS, FILTER( {[Product].[Product].[Product].Members}, ([Measures].[Internet Sales Amount] > [Measures].[Reseller Sales Amount]) AND NOT ( [Product].[Category].CurrentMember IS [Product].[Category].[Clothing] OR [Product].[Category].CurrentMember IS [Product].[Category].[Accessories] ) ) ON ROWS FROM [Step-by-Step];
NONEMPTY 函数 的用法
在我的第四章学习笔记中提到了NON EMPTY 关键字 的使用,它可以过滤掉数据为空的那些记录。
NON EMPTY 关键字是对最终查询出来的结果进行过滤,清除为结果为空的记录,比如行上的一条记录所有列上的值均为空,那么这条记录将会被清除掉。
但是如果需要在形成最终查询结果之前,对参与的集合进行过滤的话,那么就应该使用 NONEMPTY 函数。
NonEmpty( {Set1} [,{Set2}])
示例一 先回顾下 NON EMPTY 关键字
SELECT {([Measures].[Reseller Sales Amount])} ON COLUMNS, NON EMPTY {[Product].[Product].[Product].Members} ON ROWS FROM [Step-by-Step]
NON EMPTY 的作用是在 结果查询出来之后,对ROWS 轴上的所有数据进行过滤,为空的数据将不会出现。
示例二 – 使用 NONEMPTY 函数
SELECT {([Measures].[Reseller Sales Amount])} ON COLUMNS, NonEmpty( {[Product].[Product].[Product].Members}, {([Measures].[Reseller Sales Amount])} ) ON ROWS FROM [Step-by-Step];
感觉上 NON EMPTY 关键字的使用和 NONEMPTY 函数的使用结果是一样的,但是实际上有很大的区别。在这个例子中,是首先对集合中 Product 层次结构下的成员进行过滤,过滤的对象是那些 Reseller Sales Amount 记录为空的 Product 成员,在集合这个层次上就开始过滤。
示例三 – 使用 NONEMPTY 函数过滤轴
SELECT {([Measures].[Internet Sales Amount]) ,([Measures].[Reseller Sales Amount])} ON COLUMNS, NonEmpty( {[Product].[Product].[Product].Members}, {([Measures].[Reseller Sales Amount])} ) ON ROWS FROM [Step-by-Step];
很显然,对[Product].[Product].[Product] 层次结构的成员开始过滤,过滤掉那些 Reseller Sales Amount 为空的成员,然后再和其它的成员形成元组和集合并返回。
如何证明?
示例四 – 使用NONEMPTY 函数
SELECT {([Measures].[Internet Sales Amount])} ON COLUMNS, NonEmpty( {[Product].[Product].[Product].Members}, {([Measures].[Reseller Sales Amount])} ) ON ROWS FROM [Step-by-Step];
对比示例三,查询的结果中 Internet Sales Amount 中还有为空的记录,说明这些记录是没有被过滤的,也说明了这些返回的记录,它们的 Reseller Sales Amount 是不为空的。