《Microsoft SQL Server 2008 MDX Step by Step》学习笔记九:导航结构层次

 

SQL Server 2008中SQL应用系列及BI笔记系列--目录索引

导读:本文介绍MDX中的导航结构层次(Hierarchies)。成员(Member)之间的关系可以用家族来描述。本文以此为基础,介绍了

■1、访问直系亲属关系(Immediate Relatives)

■2、访问延伸亲属关系(Extended Relatives)

■3、在一个级别(Level)内导航

本文所用数据库和所有源码,请到微软官网下载

成员(Member)之间的关系可以用家族来描述。(其中Siblings是兄弟、旁支的意思,照顾下E文不好的朋友,呵呵)

下面我们以此为类,演示如何访问直系亲属和非直系亲属。

1、访问直系亲属关系(Immediate Relatives)

直系亲属的访问函数如下:

为了更好理解直系亲属关系,准备一个原始例子

例8-1

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

我们增加Parent属性:

例8-2

WITH 
MEMBER [Measures].[Percent of Parent] AS 
([Measures].[Reseller Sales Amount])/ 

[Product].[Product Categories].CurrentMember.Parent, 
[Measures].[Reseller Sales Amount] 

,FORMAT="Percent"
 
SELECT 

([Measures].[Reseller Sales Amount]), 
([Measures].[Percent of Parent]
} ON COLUMNS, 
{[Product].[Product Categories].Members} ON ROWS 
FROM [Step-by-Step] 
;

这个结果还有有一些刺眼,特别是第一条记录这样的。因为除数为0。

我们改进一下:

例8-3

WITH
MEMBER [Measures].[Percent of Parent] AS
IIF(
[Product].[Product Categories].CurrentMember.Parent Is Null, 
Null,
([Measures].[Reseller Sales Amount])/
(
[Product].[Product Categories].CurrentMember.Parent,
[Measures].[Reseller Sales Amount]
)
)
,FORMAT="Percent"
SELECT
{
([Measures].[Reseller Sales Amount]),
([Measures].[Percent of Parent])
} ON COLUMNS,
{
[Product].[Product Categories].Members
} ON ROWS
FROM [Step-by-Step]
;

顺便我们介绍一个有用的函数Rank(http://msdn.microsoft.com/zh-cn/library/ms144726.aspx),与SQL中的Rank类似。

例如如下查询:

例8-4

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

我们进行排名:

例8-5

WITH 
MEMBER [Measures].[Sibling Rank] AS
Rank(
[Product].[Product Categories].CurrentMember,
[Product].[Product Categories].CurrentMember.Siblings,
([Measures].[Reseller Sales Amount])
)

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

排名有了,再改进一下排序:

例8-6

WITH 
MEMBER [Measures].[Sibling Rank] AS
Rank(
[Product].[Product Categories].CurrentMember,
[Product].[Product Categories].CurrentMember.Siblings,
([Measures].[Reseller Sales Amount])
)
SELECT
{
([Measures].[Reseller Sales Amount]),
([Measures].[Sibling Rank])
} ON COLUMNS,
{
Order(
{[Product].[Product Categories].Members},
([Measures].[Sibling Rank]),
ASC
)
} ON ROWS
FROM [Step-by-Step]
;

2、访问延伸亲属关系(Extended Relatives)

其中相比直系关系,多了几个Flag:

我们以上面的例8-3为例,首先我们增加一个Ancestor

例8-7

WITH
MEMBER [Measures].[Percent of Parent] AS
IIF(
[Product].[Product Categories].CurrentMember.Parent Is Null, 
Null,
([Measures].[Reseller Sales Amount])/
(
[Product].[Product Categories].CurrentMember.Parent,
[Measures].[Reseller Sales Amount]
)
)
,FORMAT="Percent"
MEMBER [Measures].[Percent of Category] AS
([Measures].[Reseller Sales Amount])/
(
Ancestor(
[Product].[Product Categories].CurrentMember,
[Product].[Product Categories].[Category]
),
[Measures].[Reseller Sales Amount]
)
,FORMAT="Percent"
SELECT
{
([Measures].[Reseller Sales Amount]),
([Measures].[Percent of Parent]),
([Measures].[Percent of Category])
} ON COLUMNS,
{[Product].[Product Categories].Members} ON ROWS
FROM [Step-by-Step]
;

仿上,我们进行改进:

例8-8

WITH
MEMBER [Measures].[Percent of Parent] AS
IIF(
[Product].[Product Categories].CurrentMember.Parent Is Null, 
Null,
([Measures].[Reseller Sales Amount])/
(
[Product].[Product Categories].CurrentMember.Parent,
[Measures].[Reseller Sales Amount]
)
)
,FORMAT="Percent"
MEMBER [Measures].[Percent of Category] AS
IIF(
Ancestor(
[Product].[Product Categories].CurrentMember,
[Product].[Product Categories].[Category]
) Is Null, 
Null,
([Measures].[Reseller Sales Amount])/
(
Ancestor(
[Product].[Product Categories].CurrentMember,
[Product].[Product Categories].[Category]
),
[Measures].[Reseller Sales Amount]
)
)
,FORMAT="Percent"
SELECT
{
([Measures].[Reseller Sales Amount]),
([Measures].[Percent of Parent]),
([Measures].[Percent of Category])
} ON COLUMNS,
{[Product].[Product Categories].Members} ON ROWS
FROM [Step-by-Step]
;

下面我们尝试穿越“血缘关系”计算Product的百分比贡献。

例8-9

SELECT
{([Measures].[Reseller Sales Amount])} ON COLUMNS,
{([Product].[Product Categories].[Product].[Mountain-200 Black, 42])} ON ROWS
FROM [Step-by-Step]
;

例8-10

SELECT
{([Measures].[Reseller Sales Amount])} ON COLUMNS,
{
Ascendants(
[Product].[Product Categories].[Product].[Mountain-200 Black, 42]
)
} ON ROWS
FROM [Step-by-Step]
;

例8-11

SELECT
{([Measures].[Reseller Sales Amount])} ON COLUMNS,
Hierarchize(
{
Ascendants(
[Product].[Product Categories].[Product].[Mountain-200 Black, 42]
)
}
) ON ROWS
FROM [Step-by-Step]
;

例8-12

WITH
MEMBER [Measures].[Percent Contribution Reseller Sales] AS 
(
[Product].[Product Categories].[Product].[Mountain-200 Black, 42],
[Measures].[Reseller Sales Amount]
) / 
([Measures].[Reseller Sales Amount])
,FORMAT="Percent"
SELECT
{
([Measures].[Reseller Sales Amount]),
([Measures].[Percent Contribution Reseller Sales])
} ON COLUMNS,
Hierarchize(
{
Ascendants(
[Product].[Product Categories].[Product].[Mountain-200 Black, 42]
)
}
) ON ROWS
FROM [Step-by-Step]
;

下面我们组装一个给定分类的后裔集合

例8-13

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

例8-14

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

例8-15

SELECT
{([Measures].[Reseller Sales Amount])} ON COLUMNS,
Descendants(
{[Product].[Product Categories].[Category].[Bikes]},
[Product].[Product Categories].[Subcategory],
AFTER
) ON ROWS
FROM [Step-by-Step]
;

After标志符提供了SubCategory以下的后裔集合

例8-16

SELECT
{([Measures].[Reseller Sales Amount])} ON COLUMNS,
Descendants(
{[Product].[Product Categories].[Category].[Bikes]},
[Product].[Product Categories].[Subcategory],
SELF_AND_AFTER
) ON ROWS
FROM [Step-by-Step]
;

SELF_AND_AFTER标志符提供了SubCategory及以下的后裔集合

例8-17

SELECT
{([Measures].[Reseller Sales Amount])} ON COLUMNS,
Descendants(
{[Product].[Product Categories].[Category].[Bikes]},
[Product].[Product Categories].[Subcategory],
BEFORE_AND_AFTER
) ON ROWS
FROM [Step-by-Step]
;

BEFORE_AND_AFTER标志符提供了包含SubCategory的上级分类的所有后裔集合

大家有兴趣可以了解一下几个相关的成员函数:

IsAncestor(http://msdn.microsoft.com/zh-cn/library/ms144842.aspx

IsSibling(http://msdn.microsoft.com/zh-cn/library/ms144749.aspx

IsLeaf(http://msdn.microsoft.com/zh-cn/library/ms144932.aspx

例8-18

WITH
MEMBER [Measures].[Number of Children] AS
IIF(
IsLeaf([Product].[Product Categories].CurrentMember),
"N/A",
COUNT(
[Product].[Product Categories].CurrentMember.Children
)
)
SELECT
{[Measures].[Number of Children]} ON COLUMNS,
{[Product].[Product Categories].Members} ON ROWS
FROM [Step-by-Step]

3、在一个级别(Level)内导航

在一个级别内导航会用到几个函数:

比如计算月之间的百分比差距

例8-19

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

例8-20

WITH
MEMBER [Measures].[Prior Period Reseller Sales] AS
([Date].[Calendar].CurrentMember.PrevMember,[Measures].[Reseller Sales Amount])
,FORMAT="Currency"
SELECT
{
([Measures].[Reseller Sales Amount]),
([Measures].[Prior Period Reseller Sales])
} ON COLUMNS,
{[Date].[Calendar].[Month].Members} ON ROWS
FROM [Step-by-Step]
;

例8-21

WITH
MEMBER [Measures].[Prior Period Reseller Sales] AS
([Date].[Calendar].CurrentMember.PrevMember,[Measures].[Reseller Sales Amount])
,FORMAT="Currency"
MEMBER [Measures].[Change in Reseller Sales] AS
([Measures].[Reseller Sales Amount]) - ([Measures].[Prior Period Reseller Sales])
,FORMAT="Currency"
SELECT
{
([Measures].[Reseller Sales Amount]),
([Measures].[Prior Period Reseller Sales]),
([Measures].[Change in Reseller Sales])
} ON COLUMNS,
{[Date].[Calendar].[Month].Members} ON ROWS
FROM [Step-by-Step]
;

例8-22

WITH
MEMBER [Measures].[Prior Period Reseller Sales] AS
([Date].[Calendar].CurrentMember.PrevMember,[Measures].[Reseller Sales Amount])
,FORMAT="Currency"
MEMBER [Measures].[Change in Reseller Sales] AS
([Measures].[Reseller Sales Amount]) - ([Measures].[Prior Period Reseller Sales])
,FORMAT="Currency"
MEMBER [Measures].[Percent Change in Reseller Sales] AS
([Measures].[Change in Reseller Sales])/
([Measures].[Prior Period Reseller Sales])
,FORMAT="Percent"

SELECT
{
([Measures].[Reseller Sales Amount]),
([Measures].[Prior Period Reseller Sales]),
([Measures].[Change in Reseller Sales]),
([Measures].[Percent Change in Reseller Sales])
} ON COLUMNS,
{[Date].[Calendar].[Month].Members} ON ROWS
FROM [Step-by-Step]
;

如果觉得最后一列格式不够完美,读者可以自行修正一下。

小结:

本文介绍MDX中的导航结构层次(Hierarchies)。成员(Member)之间的关系可以用家族来描述。本文包含了比较多的函数。

参考资源:

1、MDX官方教程(http://msdn.microsoft.com/zh-cn/library/ms145506.aspx

MDX导航结构层次:《Microsoft SQL Server 2008 MDX Step by Step》学习笔记九的更多相关文章

  1. 《Microsoft Sql server 2008 Internals》读书笔记--第六章Indexes:Internals and Management(1)

    <Microsoft Sql server 2008 Internals>索引文件夹: <Microsoft Sql server 2008 Internals>读书笔记--文 ...

  2. Microsoft SQL Server 2008 R2 安装卸载

    问题 问题1 标题: Microsoft SQL Server 2008 R2 安装程序 ------------------------------ 出现以下错误: Could not open k ...

  3. Microsoft SQL Server 2008 R2官方中文版(SQL2008下载).rar

    Microsoft SQL Server 2008 R2官方中文版(SQL2008下载).rar

  4. SQL Server 2008教程和Microsoft® SQL Server® 2008 R2 SP2 - Express Edition下载

    教程 SQL Server 2008 Tutorialhttp://www.quackit.com/sql_server/sql_server_2008/tutorial/ 数据库下载 Microso ...

  5. Microsoft SQL Server 2008 基本安装说明

    Microsoft SQL Server 2008 基本安装说明 安装SQL2008的过程与SQL2005的程序基本一样,只不过在安装的过程中部分选项有所改变,当然如果只熟悉SQL2000安装的同志来 ...

  6. Microsoft SQL Server 2008 R2 中文安装说明

    Microsoft SQL Server 2008 基本安装说明 安装SQL2008的过程与SQL2005的程序基本一样,只不过在安装的过程中部分选项有所改变,当然如果只熟悉SQL2000安装的同志来 ...

  7. Microsoft SQL Server 2008 安装图解(Windows 7)

    简介 本文详细记录了一次完整的Microsoft SQL Server 2008在Windows 7操作系统上的安装过程.注意:Microsoft SQL Server 2008与Windows 7操 ...

  8. 数据库备份和恢复秩序的关系(周围环境:Microsoft SQL Server 2008 R2)

    让我们来看看在备份序列新手 --1.塔建环境(生成测试数据和备份文件) /* 測试环境: Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64) ...

  9. Microsoft SQL Server 2008 R2数据库备份 - 人工备份

    业务介绍 数据库人工备份是指由相关管理人员通过主动的手工方式备份数据库文件.在一些特殊的时间节点,如重要资料的录入完成.软硬件环境更新前等需要特别关注数据库安全的时候,一定要进行数据库的人工备份,以保 ...

随机推荐

  1. C程序设计语言习题(1-12)

    统计行数.单词数,字符数的程序: #include<stdio.h> #define IN 1 /*在单词内*/ #define OUT 0 /*在单词外*/ int main() { i ...

  2. CodeFrist、ModelFirst、DatabaseFirst

    一.CodeFirst 使用System.Data.Entity.DbContext与System.Data.Entity.DbSet构建的数据模型,没有可视化文件但只有实体类的称为CodeFirst ...

  3. Unity3D笔记 愤怒的小鸟<四> 实现Selelction界面

    一直跟着龚老师用js写,VS智能感应用习惯后发现这里用js对初学者比较蛋疼,MONO有提示但是还是无法和VS媲美就目前来看.所以这次还是换成熟悉的VS来开发. 目标:实现关卡页面 跑起来的效果如下: ...

  4. java不足前面补0

    // 0 代表前面补充0 // 3代表长度为3 // d 代表参数为正数型 result=String.format("%0"+3+"d",result);

  5. ubuntu下中文乱码解决方案(全)

    转自 http://www.cnblogs.com/end/archive/2011/04/19/2021507.html   1.ibus输入法 Ubuntu 系统安装后已经自带了ibus输入法,在 ...

  6. empty对如下8种情况返回true

    1.strrchr函数 在W3School站点上的注释如下: strrchr() 函数查找字符串在另一个字符串中最后一次出现的位置,并返回从该位置到字符串结尾的所有字符.如果成失败,否则返回 fals ...

  7. list,set中可以存放Object类型对象

    List<JSONObject> series = new ArrayList<JSONObject>();

  8. java 多线程研究:锁的概念

    java多线程:锁 java的多线程中的锁是干嘛的呢?在网上找了很多博客,大都是很专业的语言,让我一时间摸不着头脑.下面分三个部分来总结多线程中的锁的概念. 一,基础概念: 多线程在运行的时候可能会遇 ...

  9. 2.4scope

    name_scope variable_scope scope (name_scope/variable_scope) from __future__ import print_function im ...

  10. (sklearn)机器学习模型的保存与加载

    需求: 一直写的代码都是从加载数据,模型训练,模型预测,模型评估走出来的,但是实际业务线上咱们肯定不能每次都来训练模型,而是应该将训练好的模型保存下来 ,如果有新数据直接套用模型就行了吧?现在问题就是 ...