代码改变世界

MDX Step by Step 读书笔记(六) - Building Complex Sets (复杂集合的处理) - Filtering Sets

2013-04-25 17:25  BIWORK  阅读(1241)  评论(2编辑  收藏  举报

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 是不为空的。

更多 BI 文章请参看 BI 系列随笔列表 (SSIS, SSRS, SSAS, MDX, SQL Server)  如果觉得这篇文章看了对您有帮助,请帮助推荐,以方便他人在 BIWORK 博客推荐栏中快速看到这些文章。