MDX 中最大值和最小值

MDX 中最大值和最小值函数的语法和之前看到的 Sum 以及 Aggregate 等聚合函数基本上是一样的:

Max( {Set} [, Expression])

Min( {Set} [, Expression])

直接看例子,先查询出所有 Sub Category 下的 Reseller Sales Amount。

然后使用 MAX 函数查询出 Sub Category 下最大的 Reseller Sales Amount。在这里查询的范围即 SET 集合是 Sub Category 的所有成员,比较大小的依据是 Reseller Sales Amount,即在 SET 集合中查找 Reseller Sales Amount 的最大值。

比较每个 Sub Category 的 Reseller Sales Amount 和最大值的百分比。

WITH
MEMBER [Measures].[Percent of Max]
AS
([Measures].[Reseller Sales Amount]) / ([Measures].[Max Sales By Subcategory])
, FORMAT_STRING="Percent"
MEMBER [Measures].[Max Sales By Subcategory] AS
Max(
{[Product].[Subcategory].[Subcategory].Members},
([Measures].[Reseller Sales Amount])
)
SELECT
{
([Measures].[Reseller Sales Amount]),
([Measures].[Percent of Max])
} ON COLUMNS,
{[Product].[Subcategory].[Subcategory].Members} ON ROWS
FROM [Step-by-Step]

注意 Max、Min 函数与 TopCount 函数的区别:

Max、Min 函数返回的是在集合中元组对应表达式中最大或者最小的值,但 TopCount 是根据表达式查找集合中的成员。

下面查找 Reseller Sales Amount 最高的那个 Subcategory 成员。

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

统计集合中的元组 Count( {Set} [, Flag])

与前面的 MDX 聚合函数一样操作的对象都是集合 SET。Flag 的作用是:如果没有 Flag 或者指定 INCLUDEEMPTY,那么 Count 函数就直接返回集合中元组的数量;如果指定了 EXCLUDEEMPTY ,那么将返回与当前度量值相关联的非空的元组。

查询 Product 级别下所有成员的 Internet Sales Amount 和 Reseller Sales Amount,可以从下面的查询中看出不是所有产品都有 Internet Sales Amount 或者 Reseller Sales Amount 的销售记录。

COUNT 一下各个 Category 下 Product 成员的个数 -

WITH MEMBER [Measures].[Count of Products]
AS
COUNT(
EXISTING {([Product].[Product].[Product].Members)}
)
SELECT
[Measures].[Count of Products] ON COLUMNS,
{[Product].[Category].Members} ON ROWS
FROM [Step-by-Step]

统计 Category 下 Reseller Sales Amount 大于等于 Internet Sales Amount 的 Products。

WITH MEMBER [Measures].[Count of Products]
AS
COUNT(
EXISTING {([Product].[Product].[Product].Members)}
)
MEMBER [Measures].[Reseller vs Internet Count of Products]
AS
COUNT(
FILTER(
EXISTING {([Product].[Product].[Product].Members)},
[Measures].[Reseller Sales Amount] >= [Measures].[Internet Sales Amount]
)
)
SELECT
{[Measures].[Count of Products],
[Measures].[Reseller vs Internet Count of Products]} ON COLUMNS,
{[Product].[Category].Members} ON ROWS
FROM [Step-by-Step]

上面的查询结果中仍然有不准确的地方,因为在统计过程中包含了 Reseller Sales Amount 为 NULL, Internate Sales Amount 为 NULL 或者两者都为 NULL 的元组,实际上这类元组应该在统计的时候要被排除掉。

因此,加上 EXCLUDEEMPTY 关键字再来查询一下 -

但是通过观察最后的查询结果发现尽管使用了 EXCLUDEEMPTY 关键字也没有什么变化,但是确实有一些 Products 是没有 Reseller Sales Amount 数据的。其原因就在于这里会造成 Infinite Recursion 错误,只不过在这里被自动处理掉了。

有关 Infinite Recursion 的内容可以参看 MDX Step by Step 读书笔记(五) - Working with Expressions (MDX 表达式) - Infinite Recursion 和 SOLVE_ORDER 原理解析

可以通过 CrossJoin {[Measures].[Reseller Sales Amount]} 来解决这个问题,因为这样 COUNT 的时候就知道了上下文环境,元组中关联的度量值对象是 {[Measures].[Reseller Sales Amount]}。

WITH MEMBER [Measures].[Count of Products]
AS
COUNT(
EXISTING {([Product].[Product].[Product].Members)}
)
MEMBER [Measures].[Reseller vs Internet Count of Products]
AS
COUNT(
FILTER(
EXISTING {([Product].[Product].[Product].Members)},
[Measures].[Reseller Sales Amount] >= [Measures].[Internet Sales Amount]
)
)
MEMBER [Measures].[NOEMPTY Reseller vs Internet Count of Products]
AS
COUNT(
FILTER(
EXISTING {([Product].[Product].[Product].Members)},
[Measures].[Reseller Sales Amount] >= [Measures].[Internet Sales Amount]
)* {[Measures].[Reseller Sales Amount]},
EXCLUDEEMPTY
)
SELECT
{[Measures].[Count of Products],
[Measures].[Reseller vs Internet Count of Products],
[Measures].[NOEMPTY Reseller vs Internet Count of Products]} ON COLUMNS,
{[Product].[Category].Members} ON ROWS
FROM [Step-by-Step]

DistinctCount 函数

MDX 提供了另外一种 COUNT 的形式 - DistinctCount,它可以在执行 COUNT 之前先忽略掉空的以及重复的元组然后进行统计。它其实在操作上等同于在 COUNT 函数中使用 DISTINCT 关键字:COUNT(DISTINCT ({SET}), EXCLUDEEMPTY)

它的实际语法是:DistinctCount({SET})

但是如果仅仅是需要去掉重复元组后再统计 COUNT ,并且也允许包含空的元组的统计,那么就应该使用:

COUNT(DISTINCT ({SET})) 或者 COUNT(DISTINCT ({SET}), INCLUDEEMPTY)

Generate 函数

Generate ({Set}, Expression) ,Generate 函数在这一篇笔记中已经介绍过了 -

MDX Step by Step 读书笔记(六) - Building Complex Sets (复杂集合的处理) - Generate 和 Extract 函数的使用

简单回顾一下这个函数,它类似于一个循环,相当于在集合中的每一个元组都去匹配一下表达式,符合要求的元组留下来并最终和其它一样满足要求的元组共同组成一个新的集合 SET 返回。

它还有另外的一种形式可以在聚合中用到:Generate({Set}, Expression [, Delimiter])

在这个形式中,Generate 函数仍然会迭代 SET 集合中的每一个元组并匹配表达式中的内容,符合条件的元组根据 Delimiter 分割符与其它元组形成一个字符串。

WITH
MEMBER [Measures].[Products] AS
Count(
EXISTING {[Product].[Product].[Product].Members}
)
MEMBER [Measures].[Products List] AS
Generate(
EXISTING {[Product].[Product].[Product].Members},
[Product].[Product].CurrentMember.Name,
" | "
)
SELECT
{
([Measures].[Products]),
([Measures].[Products List])
} ON COLUMNS,
{[Product].[Subcategory].Members} ON ROWS
FROM [Step-by-Step]

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

MDX Step by Step 读书笔记(七) - Performing Aggregation 聚合函数之 Max, Min, Count , DistinctCount 以及其它 TopCount, Generate的更多相关文章

  1. MDX Step by Step 读书笔记(七) - Performing Aggregation 聚合函数之 Sum, Aggregate, Avg

    开篇介绍 SSAS 分析服务中记录了大量的聚合值,这些聚合值在 Cube 中实际上指的就是度量值.一个给定的度量值可能聚合了来自事实表中上千上万甚至百万条数据,因此在设计阶段我们所能看到的度量实际上就 ...

  2. 《利用python进行数据分析》读书笔记--第九章 数据聚合与分组运算(一)

    http://www.cnblogs.com/batteryhp/p/5046450.html 对数据进行分组并对各组应用一个函数,是数据分析的重要环节.数据准备好之后,通常的任务就是计算分组统计或生 ...

  3. Machine Learning for hackers读书笔记(七)优化:密码破译

    #凯撒密码:将每一个字母替换为字母表中下一位字母,比如a变成b. english.letters <- c('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i' ...

  4. 【锋利的Jquery】读书笔记七

    第七章  jquery插件 管理cookie的插件--cookie jquery插件太多没什么好讲的,百度太多 说以下 cookie插件 <!DOCTYPE html> <html& ...

  5. Android驱动开发读书笔记七

    第七章 (一)创建设备文件 1.使用cdev_init函数初始化cdec 描述设备文件需要一个cdev结构体,代码如下: struct cdev{ struct kobject kobj; struc ...

  6. 《CLR.via.C#第三版》第二部分第13章节 接口 读书笔记(七)

    这章的书写感觉很普通,是些基础的认知知识. 其中一点的重要认知,泛型接口的好处(其实也是使用泛型的好处之一):编译时类型安全&处理值类型时减少装箱. 再说点书上没有的.本来这些知识我打算另外分 ...

  7. 深入理解linux网络技术内幕读书笔记(七)--组件初始化的内核基础架构

    Table of Contents 1 引导期间的内核选项 2 注册关键字 3 模块初始化代码 引导期间的内核选项 linux运行用户把内核配置选项传给引导记录,然后引导记录再把选项传给内核. 在引导 ...

  8. Spring揭秘 读书笔记 七 BeanFactory的启动分析

    首先,先看我自己画的BeanFactory启动时的时序图. 第一次接触时序图,可能有些地方画的不是很符合时序图的规则,大家只关注调用顺序即可. public static void main(Stri ...

  9. how tomcat works读书笔记 七 日志记录器

    大家可以松一口气了,这个组件比较简单,这一节和前面几节想比,也简单的多. Logger接口 Tomcat中的日志记录器都必须实现org.apache.catalina.Logger接口. packag ...

随机推荐

  1. 简易图书管理系统(主要是jsp的练习)

    1:首先设计用户表和图书表,设计的字段和类型如下图所示 1.1:用户表user 1.2:图书表book 2:第二写实体类user.java和book.java package com.bie.po; ...

  2. mongo3.x配置说明

    Mongodb 3.x配置说明,本文内容忽略了Enterprise版和一些不常用的配置. 一.配置说明 在Mongod安装包中,包含2个进程启动文件:mongod和mongos:其中mongd是核心基 ...

  3. win10定时执行php脚本

    转自http://www.cnblogs.com/wenhainan/p/6962089.html 第一步:确认windows上是否配置好了php环境变量,我用xampp安装的lamp环境,默认已经配 ...

  4. Codeforces Round #309 (Div. 2) -D. Kyoya and Permutation

    Kyoya and Permutation 这题想了好久才写出来,没看题解写出来的感觉真的好爽啊!!! 题目大意:题意我看了好久才懂,就是给你一个序列,比如[4, 1, 6, 2, 5, 3],第一个 ...

  5. 【noip模拟赛4】Matrix67的派对 dfs

    描述 Matrix67发现身高接近的人似乎更合得来.Matrix67举办的派对共有N(1<=N<=10)个人参加,Matrix67需要把他们安排在圆桌上.Matrix67的安排原则是,圆桌 ...

  6. 6-3 二叉树的重建 uva536

    已知先序和中序  求后序 可以有两种方式输出 一种是建好树按照树输出 一种是不建树  在遍历的过程中存入vector  再倒叙输出 #include<bits/stdc++.h> usin ...

  7. 【Java】 剑指offer(23) 链表中环的入口结点

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 一个链表中包含环,如何找出环的入口结点?例如,在图3.8的链表中, ...

  8. EXIST子查询

    已知关系模式:S(Sno,Sname,Sclass),C(Cno,Cname,Cteacher),SC(Sno,Cno,Scgrade).其中,S为学生关系:Sno学号, Sname姓名,Sclass ...

  9. QT5入门之23 -QT串口编程(转)

    QT5入门之23 -QT串口编程   QT5有专门的串口类: QSerialPort:提供访问串口的功能 QSerialPortInfo:提供系统中存在的串口的信息 具体使用方法: 1.在pro文件中 ...

  10. Autodesk系列软件下载

    摘要: 写在前面:下载后如有需要压缩密码的请先使用压缩软件(如:2345好压)打开压缩包,在压缩包的注释或者文本信息中会给出压缩密码!如若没有请私信! 1.3ds Max软件(64位) Autodes ...