代码改变世界

MDX Step by Step 读书笔记(六) - Building Complex Sets (复杂集合的处理) - TopCount - BottomCount - Head - Tail - Item 函数的使用

2013-04-24 23:10  BIWORK  阅读(2181)  评论(1编辑  收藏  举报

Retrieving the First or Last Tuples of a Set 在集合中获取第一个或者最后一个元组

TopCount  和 ButtomCount 函数

先看一个之前的例子,示例一 使用Order 排序

SELECT
{   ([Measures].[Reseller Sales Amount]) } ON COLUMNS,
Order(
    {[Product].[Subcategory].[Subcategory].Members},
    ([Measures].[Reseller Sales Amount]),
    BDESC
) ON ROWS
FROM [Step-by-Step]

查询结果如下 – 对 Subcategory 下的成员按照 Reseller Sales Amount 降序排序,并且在排序的过程中打破了层次结构的分类,因为 DESC 和 ASC 的排序规则是基于层次结构的。

                  

像这样的排序查询可以很快的发现销售额最高或者最低的那些产品子类,但是有时候我们的查询往往可能只需要返回若干条或者有限的5条销售额最高或者最低的记录,这样的话就可以使用TopCount 或者 BottomCount 来实现了。

TopCount( {Set}, n [, Expression])

BottomCount( {Set}, n [, Expression])

示例二 使用 TopCount 查询有限的排序记录

SELECT
{   ([Measures].[Reseller Sales Amount]) } ON COLUMNS,
TopCount(
  {[Product].[Subcategory].[Subcategory].Members},
  5,
  ([Measures].[Reseller Sales Amount])
) ON ROWS
FROM [Step-by-Step]

对比示例一,返回的是销售额最高的5条记录,并且可以看出排序后的数据也是打破了层次结构的限制。

示例三 倒序排序

SELECT
{   ([Measures].[Reseller Sales Amount]) } ON COLUMNS,
ORDER(
  {[Product].[Subcategory].[Subcategory].Members},
  ([Measures].[Reseller Sales Amount]),
  BASC
) ON ROWS
FROM [Step-by-Step];

示例四 使用 BottomCount 取最后的5条记录

SELECT
{   ([Measures].[Reseller Sales Amount]) } ON COLUMNS,
BottomCount(
  {[Product].[Subcategory].[Subcategory].Members},
  5,
  ([Measures].[Reseller Sales Amount])
) ON ROWS
FROM [Step-by-Step];

查询结果 – 显示有 NULL 的原因是因为这几类子产品的确没有销售记录,如果不想返回 NULL 记录的话可以通过 Filter 和 NONEmpty 函数来解决这些问题。

Head 和 Tail 函数 (头部和尾部函数)

Head({Set} [,n])

Tail({Set} [,n])

Head 和 Tail 函数从一个集合的头部或者尾部返回指定数量的元祖,它们与 TopCount 和 BottomCount 的区别就是 Head 和 Tail 函数不会对集合里的元组进行排序,只是返回指定数量的元组并以集合形式返回。如果没指定返回的数量,那么就返回集合的第一个或者最后一个元组,需要的时候可以结合Order 来使用。

一般的查询

SELECT
{([Measures].[Reseller Sales Amount])} ON COLUMNS,
{[Product].[Subcategory].[Subcategory].Members} ON ROWS
FROM [Step-by-Step];

按默认顺序返回

没有指定数目的时候

SELECT
{   ([Measures].[Reseller Sales Amount]) } ON COLUMNS,
HEAD(   {[Product].[Subcategory].[Subcategory].Members} ) ON ROWS
FROM [Step-by-Step];

使用Head默认就返回第一条数据

指定数量,比如10条数据 (有的时候当查询数据很大,但是可能仅仅只需要一部分测试数据时使用Head 很方便)。

SELECT
{   ([Measures].[Reseller Sales Amount]) } ON COLUMNS,
HEAD(     {[Product].[Subcategory].[Subcategory].Members}     ,10   ) ON ROWS
FROM [Step-by-Step];

按照默认顺序返回10条数据

也可以结合Order 返回排序后的几条数据,实际上等同于 TopCount或者BottomCount 的效果。

SELECT
{   ([Measures].[Reseller Sales Amount]) } ON COLUMNS,
HEAD(
  Order(
      {[Product].[Subcategory].[Subcategory].Members},
      ([Measures].[Reseller Sales Amount]),
      BDESC
    ),
  5
) ON ROWS
FROM [Step-by-Step];

The Item Function 使用Item 函数

上面的 TopCount,BottomCount,Head,Tail 函数返回的都是集合,但有的时候我们可能仅仅需要查询到集合中的一个元组,而无论这个集合有没有排序,这时可以使用 Item 函数。

{Set} | (Tuple).Item( i )

{Set}.Item( String1 [, String2, . . ., Stringn] )

在第一种形式中,可以通过提供编号返回集合中的一个元组。在集合中的每一个元组都可以通过一个有序的值来访问,在集合中的第一个元组它的编号是0。

在第二种语法中,可以通过字符串参数的形式返回元组,但是这种方式有点复杂用的也不是非常多。

另外要注意的是,Item 函数不仅仅用于返回集合中的元组,当定位到一个元组的时候,使用这个函数还可以访问到具体的Member 成员。如果要访问元组中的成员,那么只能使用从0开始基于数字的编号来访问元组中的成员。

下面的例子中展示了如果使用 Item 函数查询这4年中的每一年 Internet 销售额最高的产品。

WITH
MEMBER [Measures].[Top Product Sales] AS {
  EXISTING
  TopCount(
    [Product].[Product].[Product].Members,     1,     ([Measures].[Internet Sales Amount])
  ) *
  {[Measures].[Internet Sales Amount]}
}.Item(0)
,FORMAT_STRING="Currency"

MEMBER [Measures].[Top Product Name] AS
{
  EXISTING
  TopCount(
    [Product].[Product].[Product].Members,
    1,
    ([Measures].[Internet Sales Amount])
  )
}.Item(0).Item(0).Name

SELECT
{
  ([Measures].[Internet Sales Amount]),
  ([Measures].[Top Product Sales]),
  ([Measures].[Top Product Name])
} ON COLUMNS,
{
  ([Date].[Calendar Year].[CY 2001]),
  ([Date].[Calendar Year].[CY 2002]),
  ([Date].[Calendar Year].[CY 2003]),
  ([Date].[Calendar Year].[CY 2004])
} ON ROWS
FROM [Step-by-Step]

查询结果 -

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