《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

posted @ 2011-11-27 09:51  邀月  阅读(1414)  评论(3编辑  收藏  举报