《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. Elasticsearch学习之快速入门案例

    1. document数据格式 面向文档的搜索分析引擎 (1)应用系统的数据结构都是面向对象的,复杂的(2)对象数据存储到数据库中,只能拆解开来,变为扁平的多张表,每次查询的时候还得还原回对象格式,相 ...

  2. 跟bWAPP学WEB安全(PHP代码)--SQL注入的一些技巧

    背景 模拟环境还是 bWAPP,只不过这个bWAPP的SQL注入有点多,一一写意义不大,在这边就利用这个环境来尝试一些SQL注入的技巧.并研究下PHP的防御代码. 普通的bWAPPSQL注入的简单介绍 ...

  3. Unity3D protobuf-net使用方式

    1.下载protobuf-net 2.创建Unity工程,创建一个Plugins文件夹,将protobuf-net解压把里面得protobuf-net放到Plugins 3.创建一个名为mcs的文本文 ...

  4. WORD Application.Documents.Open函数返回null的一种解决方法

    DCOM Config Setting for "Microsoft Office Word 97 - 2003 Document" 内部配置一切正常,但调用Application ...

  5. RDMA卡的检测方法

    1. udaddy This script covers RDMA_CM UD connections. (It establishes a set of unreliable RDMA datagr ...

  6. CentOS 6安装并开启telnet服务

    一.安装telnet yum install telnet telnet-server //安装telnet server捎带手把客户端也装了 二.配置xinetd telnet server默认会安 ...

  7. Java秒杀简单设计二:数据库表和Dao层设计

    Java秒杀简单设计二:数据库表Dao层设计 上一篇中搭建springboot项目环境和设计数据库表  https://www.cnblogs.com/taiguyiba/p/9791431.html ...

  8. MUI---上传头像功能实现

    这里使用MUI上传头像的功能是结合VUE来做的,所以: changeFace:function(){ var IMAGE_UNSPECIFIED = "image/*"; //相册 ...

  9. empty是判断一个变量是否为“空”,而isset 则是判断一个变量是否已经设置

    1.echo和print的区别php中echo和print的功能基本相同(输出),但是两者之间还是有细微差别的.echo输出后没有返回值,但print有返回值,当其执行失败时返回flase.因此可以作 ...

  10. 金字塔原理——MECE(Mutually Exclusive Collectively Exhaustive)

    一.金字塔原理 它的样子: 一个中心思想,分出下面2到N个思想支撑,每个分论点下面又有2到N个思想(事实或数据)支撑,以此类推,形状如金字塔.原则是以终为始(先结果后原因),以上统下,归纳分组,逻辑递 ...