1. 在 Analysis Service 分析服务中,Cube (多维数据集) 是以一个多维数据空间来呈现的。在Cube 中,每一个纬度的属性层次结构都形成了一个轴。沿着这个轴,在属性层次结构上的每一个成员包括 “ALL” 成员都在轴上占了一个点。

2. 包含度量值的纬度叫做事实纬度或者度量纬度,度量属性层次结构和其它属性层次结构的区别就是度量属性层次结构没有 ALL 这个成员。

3. 成员的引用 – 引用属性层次结构中的成员有很多方式,但基本的成员引用可以通过与它相关联的纬度和属性层次结构来实现: [Dimension].[Hierarchy].[Member]。

4. 理解这幅图

在 Product 纬度中有两个属性层次结构 – Category 和 Subcategory,在Date 纬度中也有两个属性层次结构 – Calendar Year 和 Fiscal Year,这两个属性层次结构在一起构成了一个用户自定义的层次结构 – Calendar-To-Fiscal Year。这四个原始的属性层次结构再加上度量值属性层次结构,在Cube 空间里总共有5个轴,那么在这个纬度空间里的点因此需要用5个元素组成的元组来定位。

5. 通过使用元组可以定位到Cube 空间中的一个点。但是在这个点上,它是以一个简单的值来显示的,这个点可以理解为 Cell – 单元格。Cell 其实是一个对象,它有很多不同的属性。当访问这个单元格时,各种不同的属性会随之返回。默认返回的属性有 VALUE 和 FORMATTED_VALUE。

6. VALUE 属性包含了聚合的度量值,这个值是在与这个单元格相关联的其它属性层次结构上聚合的度量值。

7. FORMATTED_VALUE 属性包含了以字符串形式呈现的VALUE,这种格式化在设计阶段就已经确定了,它只是用来控制最终在MDX 查询界面显示的格式, 可以通过查看 CELL PROPERTIES 来了解VALUE 和FORMATTED_VALUE。

CellOrdinal 属性表示的是在查询返回的集合中的位置。

8. 可以添加 CELL PROPERTIES 关键字,但这样的话就需要显示定义出 VALUE 和 FORMATTED_VALUE,否则这两个属性将不会被返回。

下面查询的内容将返回其它的单元格属性 FORMATTED_VALUE和 FORMAT_STRING

SELECT  FROM [Chapter 3 Cube]
WHERE (     
[Product].[Subcategory].[Mountain Bikes],     
[Date].[Calendar Year].[All Periods],     
[Date].[Fiscal Year].[All Periods],     
[Product].[Category].[Bikes],     
[Measures].[Measures].[Reseller Sales Amount]
) CELL PROPERTIES FORMATTED_VALUE, FORMAT_STRING

返回的单元格属性就没有 VALUE 和 FORMATTED_VALUE 了。

9. 局部元组(Partial Tuple) – 对比元组 Tuple而言,在局部元组中有一个或者多个成员的引用被忽略掉了,没有显式的写出来。一个完整的元组可以定位到Cube空间的一个点,Analysis Services 在处理局部元组的时候将会按照一定的规则去自动的填充在局部元组中被忽略掉的成员引用: 1. 如果成员引用被忽略,将使用属性的默认成员(即这个属性的默认值)  2. 如果成员引用被忽略并且这个成员没有默认值,那么将使用这个属性的 All 成员。 3. 如果成员引用被忽略,成员没有默认值也没有All 这个成员,那么就使用这个属性的第一个成员(这个属性下所有值集合中的第一个值)。

10. 局部元组的使用 – 当元组中缺少度量值属性成员的引用时

SELECT  FROM [Chapter 3 Cube]
WHERE (     
[Date].[Calendar Year].[All Periods],     
[Date].[Fiscal Year].[All Periods],     
[Product].[Category].[Bikes],     
[Product].[Subcategory].[Mountain Bikes],     
[Measures].[Measures].[Reseller Sales Amount]
)

查询结果是 - $26,492,684.38

这个元组中包含5个轴,其中Date 纬度上引用的都是属性层次结构中的 ALL 成员,其含义为查询 Bikes 大类下的Mountain Bikes 所有的零售额。All 成员就是表示所有年份,不考虑具体时间点或时间段的零售额,只考虑总销售额,但也明确了是在 Bikes 大类 和 Mountain Bikes 子类范围。

现在在这个完整的元组中去掉一个成员引用 –

SELECT  FROM [Chapter 3 Cube]
WHERE (       
[Date].[Calendar Year].[All Periods],       
[Date].[Fiscal Year].[All Periods],       
[Product].[Category].[Bikes],       
[Product].[Subcategory].[Mountain Bikes] )

查询结果仍然相同 - $26,492,684.38 结果相同。

此图中 Analysis Services 首先检查各个轴,也就是纬度有没有缺失。根据上面的代码能够检查到对于度量值属性层次结构这个轴右缺失,于是第一步先检查这个属性有没有默认的成员。通过检查发现这个属性默认的成员引用就是 Reseller Sales Amount, 因此就会自动将对这个成员的引用补充到这个元组中使其变成一个完整的Tuple 元组,这样再集合其它的成员引用来定位到Cube空间的某一个点。

度量值属性层次结构中的默认成员是在设计阶段定下的,因为度量值属性层次结构没有ALL这个成员,所有如果度量值属性层次结构中没有指定默认成员的话,那么第一个度量值成员将被填充到元组中。

11. 局部元组 – 当元组中缺少属性层次结构的引用时

SELECT  FROM [Chapter 3 Cube]
WHERE (       
[Product].[Category].[Bikes],       
[Product].[Subcategory].[Mountain Bikes]
)

结果 - $26,492,684.38

5个轴,其中 Date两个轴再加上度量值这个轴总共3个轴没有对应的点,即在Cube 这个空间里缺少3个轴的坐标引用,无法定位到空间的具体某一点。对于度量值成员的引用直接按照第一种规则使用默认成员引用填充,但是Date纬度上的Calendar Year和Fiscal Year 这两个属性层次结构(即轴)并没有指定默认成员,因此将使用第二规则使用All成员。

因此等同于 -

SELECT F ROM [Chapter 3 Cube]
WHERE (       
[Date].[Calendar Year].[All Periods],       
[Date].[Fiscal Year].[All Periods],       
[Product].[Category].[Bikes],       
[Product].[Subcategory].[Mountain Bikes],       
[Measures].[Measures].[Reseller Sales Amount]     
)

12. 用户自定义的属性层次结构 Calendar-To-Fiscal Year 是一个用户自定义的属性层次结构,如果要引用Calendar Year 2003 这个成员的话可以这么引用 –

[Dimension].[Hierarchy].[Member]

[Date].[Calendar-To-Fiscal Year].[CY 2003]

用户自定义的属性层次结构实际上也是来源于其它属性层次结构,所以它们的成员标识符很有可能并不是唯一的。

比如这样引用 [Date].[Calendar-To-Fiscal Year].&[2003],问题在于不清楚这里的Key 2003 是指Calendar Year 2003 还是指 Fiscal Year 2003。

因此此时需要一个Level来区分:

[Dimension].[Hierarchy].[Level].[Member]

[Date].[Calendar-To-Fiscal Year].[Calendar Year].$[2003]

但是尽管如此也会出现其它的问题,例如在用户自定义的属性层次结构中存在两个相同的FY2004 成员,这时需要加上它们的Parent 节点 -   [Date].[Calendar-To-Fiscal Year].[Calendar Year].[CY 2002].[FY 2003] [Date].[Calendar-To-Fiscal Year].[Calendar Year].[CY 2003].[FY 2003]

13. 理解用户自定义层次结构 User-Hierarchies

用户自定义层次结构上的成员实际最终引用的还是其它属性层次结构上的成员。

SELECT  FROM [Chapter 3 Cube]
WHERE (       
[Date].[Calendar-To-Fiscal Year].[Calendar Year].[CY 2003].[FY 2003]     
)

Analysis Services 首先在用户自定义层次结构中定位到在 Fiscal Year level 上的成员 FY 2003 以及与之相关联的 Calendar Year 上的 CY 2003成员,再各自定位到属性层次结构轴上的成员引用,这个结果和这里的查询结果是一样的,因为它们有相同的引用。

SELECT  FROM [Chapter 3 Cube]
WHERE (       
[Date].[Calendar Year].[CY 2003],       
[Date].[Fiscal Year].[FY 2003] )

14. 当用户自定义层次结构和属性层次结构在同一个轴上引用同一个成员时

SELECT  FROM [Chapter 3 Cube]
WHERE (       
[Date].[Calendar-To-Fiscal Year].[Calendar Year].[CY 2002].[FY 2003],       [
Date].[Fiscal Year].[FY 2003] )

不会发生冲突,因为在一条轴上定位的都是同一个点。

15. 当用户层次结构和属性层次结构在同一个轴上引用不同成员时

SELECT  FROM [Chapter 3 Cube]
WHERE (       
[Date].[Calendar-To-Fiscal Year].[Calendar Year].[CY 2002].[FY 2003],       
[Date].[Fiscal Year].[FY 2002] )

发生冲突,返回NULL,原因就在于 Analysis Service 不能确定在 Fiscal Year上到底要引用哪一个成员。

16. 如何通过Name引用一个成员 – [Dimension].[Hierarchy].[Member Name]

示例-[Product].[Category].[Bikes]

17. 如何通过Key 引用一个成员 – [Dimension].[Hierarchy].&[Member Key] 示例 – [Product].[Category].&[1]

18. 如何在用户自定义层次结构中通过某个Level来访问一个成员 – [Dimension].[Hierarchy].[Level].[Member Name] [Date].[Calendar-To-Fiscal Year].[Calendar Year].[CY 2003]

19. 如何通过元组Tuple定位到一个Cell 单元格 引用成员的结构是 […].[…].[….],引用元组是通过一对圆括号将成员括起来来定位Cube空间的一个点. ([….].[….].[….], [….].[….].[….], [….].[….].[….])

20. 如何来查看返回Cell中的其它属性 – CELL PROPERTIES

文章出处:MDX Step by Step 读书笔记(三) - Understanding Tuples (理解元组)

【转载】MDX Step by Step 读书笔记(三) - Understanding Tuples (理解元组)的更多相关文章

  1. 《你必须知道的.NET》读书笔记三:体验OO之美

    此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.依赖也是哲学 (1)本质诠释:“不要调用我们,我们会调用你” (2)依赖和耦合: ①无依赖,无耦合 ...

  2. Spring揭秘 读书笔记 三 bean的scope与FactoryBean

    本书可作为王富强所著<<Spring揭秘>>一书的读书笔记  第四章 BeanFactory的xml之旅 bean的scope scope有时被翻译为"作用域&quo ...

  3. Struts2技术内幕 读书笔记三 表示层的困惑

    表示层能有什么疑惑?很简单,我们暂时忘记所有的框架,就写一个注册的servlet来看看. index.jsp <form id="form1" name="form ...

  4. ES6读书笔记(三)

    前言 前段时间整理了ES6的读书笔记:<ES6读书笔记(一)>,<ES6读书笔记(二)>,现在为第三篇,本篇内容包括: 一.Promise 二.Iterator和for of循 ...

  5. Mastering Web Application Development with AngularJS 读书笔记(三)

    第一章笔记 (三) 一.Factories factory 方法是创建对象的另一种方式,与service相比更灵活,因为可以注册可任何任意对象创造功能.例如: myMod.factory('notif ...

  6. 读书笔记,《深入理解java虚拟机》,第三章 垃圾收集器与内存分配策略

    要实现虚拟机,其实人们主要考虑完成三件事情: 第一,哪些内存需要回收: 第二,什么时候回收: 第三,如何回收. 第二节,对象已死吗    垃圾收集其实主要是针对java堆里面的数据来说的,传统的垃圾收 ...

  7. 《实战Java高并发程序设计》读书笔记三

    第三章 JDK并发包 1.同步控制 重入锁:重入锁使用java.util.concurrent.locks.ReentrantLock类来实现,这种锁可以反复使用所以叫重入锁. 重入锁和synchro ...

  8. 《CLR.via.C#第三版》第二部分第6,7章节读书笔记(三)

    第6章讲的是类型和成员基础 重要认知:虚方法 虚方法的设计原则:设计一个类型时,应尽量减少所定义的虚方法的数量. 首先,调用虚方法的速度比调用非虚方法慢. 其次,JIT编译器不能内嵌虚方法,这进一步影 ...

  9. JavaScript DOM编程艺术读书笔记(三)

    第七章 动态创建标记 在web浏览器中往文档添加标记,先回顾下过去使用的技术: <body> <script type="text/javascript"> ...

随机推荐

  1. mybatis框架入门程序:演示通过mybatis实现数据库的模糊查询操作

    1. mybatis的基本准备操作见我的上一篇博文:https://www.cnblogs.com/wyhluckdog/p/10149480.html 2. 根据用户名查询用户信息: (1)映射文件 ...

  2. Java 连接 Hive的样例程序及解析

    以后编程基于这个样例可节省查阅API的时间. private static String driverName = "org.apache.hadoop.hive.jdbc.HiveDriv ...

  3. [Jenkins]怎样在Jenkins上面启动服务器上的批处理脚本

    New Item 在Build --> Execute Windows batch command --> 里面填写: schtasks /run /tn Start_Hub_szotqa ...

  4. SQL group by 分组后,同一组的排序后取第一条

    SELECT * FROM(                SELECT                     [SPID]                    ,[PH1]           ...

  5. 跟微软保持适当距离--Hessian + .net 实现RPC体系的企业应用

    同在一个产业链园区的XX厂因为5台Window2003服务器收到了律师函并且被迫下了12万$的采购单,虽然100万对XXX厂来数不是大数目,但是总有种被打劫的感觉. 在企业ERP应用中服务层一般都是做 ...

  6. 多个docker 挂载VOLUME的心得

    假如有一个mysql镜像 在Dockerfile中制定VOLUME /var/lib/mysql 那么当执行: docker run -d -e MYSQL_ROOT_PASSWORD=root -- ...

  7. Monokai风格的EditPlus配色方案

    EditPlus的配置文件editplus_u.ini,该文件默认在:系统盘:\Users\用户名\AppData\Roaming\EditPlus目录中.将其中的内容替换为如下即可: [Option ...

  8. IntelliJ IDEA 2017版 SpringBoot的Json字符串返回

    一.说明 SpringBoot框架已经自动封装好json字符串解析,所以我们只需要用它的注解来返回操作就可以了. 二.实战 1.书写一个实体类User,设置属性id和name package com. ...

  9. Plupload 上传详细讲解,Plupload 多实例上传,Plupload多个上传按钮--推荐使用

    今天帮朋友解决  Plupload  上传的问题,查了很多资料,资料还是挺全的,但是有点零零散散的,故整理好,合并发出来. 本教程包括: Plupload  上传详细讲. Plupload  多实例上 ...

  10. 点击导航栏tableView回到顶部

      UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector ...