专注应用,关注发展,开拓创新

<-------------------------------------------------------------------& 珍惜生命 . 善用时间 . 把握未来 . 创造价值。

BlogJava 首页 新随笔 联系 聚合 管理
  11 Posts :: 17 Stories :: 10 Comments :: 0 Trackbacks
mondrian是一个olap工具,jpviot是一个显示它处理结果的taglib,使用这2个工具可以做复
杂的统计汇总并显示
OLAP:Mondrian&JPviot

olap: online analytical processing(联机分析处理),实时的分析大量数据,其操作通常是
只读的.online意味着即使是大量的数据,系统对查询的响应也要足够快.

olap使用一种技术叫做multimensional analysis(多维分析),关系数据库将数据存成行和列的形式,多维数据表包含轴和单元.

mondrian包含4层:表示层,计算层,聚集层,存储层.

表示层:指最终呈现在用户显示器上的,以及与用户之间的交互,有许多方法来展现多维数据,
包括数据透视表,饼,柱,线状图.

计算层:分析,验证,执行MDX查询.

聚集层:一个聚集指内存中一组计算值(cell),这些值通过维列来限制.计算层发送单元请求,
如果请求不在缓存中,或者不能通过旋转聚集导出的话,聚集层向存储层发送请求.

聚合层是一个数据缓冲层,从数据库来的单元数据,聚合后提供给计算层。聚合层的主要作
用是提高系统的性能。

存储层:提供聚集单元数据和维表的成员,这些层可以不在同一机子上,但是计算和聚集层必�
朐谕惶ɑ由�.

三种需要存储的数据:1:事实数据2:聚集3:维

配置文件中的特定含义:
1:cube(立方体):是维和量的集合

2:measure(量):一个具体的测量量

3:dimension(维):一个属性或者一系列属性,通过维可以将量分类

下面是我关于jpviot的修改:jpviot是显示mondrian的一个taglib

问题1:让行和列的标题显示为中文,此问题非常简单,只需要在你的schema中设置一下编码即
可,例如在FoodMart中设置如下

<?xml version="1.0" encoding="gb2312"?>

然后可以这样描述Measure:

<Measure name="库存消耗" column="store_cost" aggregator="sum"
formatString="#,###.00"/>

所有带name属性的都可以替换成中文,jpviot会自动显示这些中文.

问题2:关于去掉Measure标题的问题:

默认生成的报表中会有这么一行
<tr>
<th rowspan="1" colspan="2" class="corner-heading"
nowrap="nowrap">&nbsp;</th><th rowspan="1" colspan="3"
class="heading-heading" nowrap="nowrap"><img height="9" width="9"
border="0" src="/jpivot/jpivot/table/drill-position-other.gif">Measures</th>
</tr>

这一行有个默认的标题是Measure,如果你不想删除这一行,而仅仅想修改这个标题的话,可以
修改
WEB-INFclassescomtonbellerjpivotmondrianresources.properties.但是注意这个文件中�
谌菪闯捎⑽拿晃侍�,如写成中文的话应该写成unicode,例如023这样的形式.

如果你要去掉这一行的话,修改配置文件和xsl恐怕做不到,我分析了其代码,最终在代码层次
上做了修改:
修改的代码为com.tonbeller.jpivot.table.ColumnAxisBuilderImpl:

将其构造函数中的setHierarchyHeader的参数修改为setHierarchyHeader(NO_HEADER);这个
函数支持3个参数,我们修改后就不会显示那个标题行了.

问题3:生成图表后自动生成chart表的问题:

我测试生成图表中的中文问题都解决了,但是每次生成chart图时会报UTF编码错误,从错误判
断应该是某个文件的编码错误,起初根据错误判断是
filter的问题,可是filter那点代码中根本不涉及编码的问题.我将很多配置文件的编码都改
了也不行.因为那个英文例子没问题,我查看了
JFreechart的一个servlet(org.jfree.chart.servlet.DisplayChart),因为jpviot就是调用
这个servlet实现绘图的,分析这个servlet我知道它会在一个临时目录生成png文件,然后交�
鴖ervlet写到浏览器的响应中去,我找到那个临时目录(tomcattemp),发现里面已经生成了正
确的中文图形.从而判断图形生成正确,但是写到浏览器中时出了问题.最后我查看能生成英�
耐急淼哪歉隼�,发觉不仅仅在html中生成图形,而且生成map.而这个map的生成全是在程序
中做的,程序生成一个xml文件,通过chart.xsl解析生成map的最终html代码.但是在程序中生
成时并没有加入编码设置,因此问题出在生成map这儿.

最终修改代码如下:

com.tonbeller.jpivot.chart.ChartComponent:

在render函数中修改如下:

String desc="<?xml version="1.0" encoding="gb2312"?>";
String xchart =desc+"n"+ "<xchart>" + writeImageMap(filename, info,
false) + "</xchart>";
这样就为xchart设置了编码.

问题4:修改jfreechart中的默认字体:

com.tonbeller.jpivot.chart.ChartComponent中定义了几种字体,但是这几种字体都是英文
字体,我将其修改为宋体:
把所有的字体定义都改为"SimSun"
注意到这儿并没有玩,如果你仅仅修改程序,仍旧会出现问题,报错说没有适合"SimSun"的ite
m
同时要修改一个配置文件:WEB-INFjpivotchartchartpropertiesform.xml
在这个配置文件中将SimSun加入其中,形式如下:

<listBox1 type="string" modelReference="fontName" label="Title font">
<listItem value="SansSerif" label="SansSerif"/>
<listItem value="Serif" label="Serif"/>
<listItem value="SimSun" label="SimSun"/>
<listItem value="Monospaced" label="Monospaced"/>
</listBox1>
posted on 2006-05-05 14:19 吴名居 阅读(1907) 评论(9)  编辑  收藏 所属分类: 数库仓库-mondrian

Feedback

# re: 简介 2006-05-05 14:35 吴名居
当设计多维表达式 (MDX) 查询时,应用程序一般查看多维数据集并将维度集合划分为两个子集:


轴维度,为多个成员检索数据的维度。

切片器维度,为单个成员检索数据的维度。(相当于在走切片操作中选择某一个具体的成员)

SELECT
{ Route.nonground.Members } ON COLUMNS,
{ Time.[1st half].Members } ON ROWS
FROM TestCube
WHERE ( [Measures].[Packages] )






每个轴维度与一个数字相关联:0 对应于 x 轴,1 对应于 y 轴,2 对应于 z 轴,等等。<index> 值是轴号。对于前 5 个轴,COLUMNS、ROWS、PAGES、SECTIONS 和 CHAPTERS 这几个别名可分别代替 AXIS(0)、AXIS(1)、AXIS(2)、AXIS(3) 和 AXIS(4) 使用。

MDX 查询无法跳过轴。也就是说,包含一个或多个 <axis_name> 值的查询不能排除低编号轴或中间轴。例如,查询不能有 ROWS 轴而无 COLUMNS 轴,或有 COLUMNS 和 PAGES 轴而无 ROWS 轴。

3:度量值如何向最终用户显示
度量值构成了提供给最终用户的多维数据集信息的核心。显示形式是表格还是图形,取决于最终用户用来浏览多维数据集的客户端应用程序,但度量值却是最终用户所关心的信息。

使用表格时,度量值是以行和列的形式显示的。尽管多维数据集的维度决定了列标题和行标题,但度量值仍是行和列中的数据。然而,如果您在多维数据集 中指定多个度量值,那么它们也会提供多个标题来区分度量值。

使用图形方式时,度量值可以用多种方式显示,其中包括线条、形状、颜色、底纹和阴影。但是,和使用表格方式一样,度量值占据中心主要区域,而维度提供外围标签。

4:如果成员的名称中有空格或数字,则要使用括号字符 [ 和 ]。尽管"时间"维度是一个词,也可在其外面加上方括号;上面的关系图中所示的成员还可表示为:

5:计算成员
还可将成员创建为 MDX 查询的一部分,以使返回的数据基于评估表达式,而不是要查询的多维数据集中所存储的数据。这些成员称为计算成员,它们提供大量的 MDX 的功能和灵活性。在 MDX 查询中用 WITH 关键字定义计算成员。例如,如果想要通过增加"包"度量值现有值的 10% 来对所有包裹进行预测估算,可以仅创建一个提供此信息的计算成员,并象使用多维数据集中的任何其它成员那样使用它,如以下示例所示。

WITH MEMBER [Measures].[PackagesForecast] AS
'[Measures].[Packages] * 1.1'
6:元组
在 MDX 中,元组根据其复杂性依照语法进行构造。如果它仅由来自单个维度的一个成员组成(通常称作简单元组),则以下语法是可接受的。

时间.[下半年]
如果它由来自不止一个维度的成员组成,则元组所表示的成员必须括在圆括号内,如以下示例所示。

(时间.[下半年], 路线.非陆地.航空)
由单个成员组成的元组也可括在圆括号内,但这不是必需的。元组常常编组成集合,以便在 MDX 查询中使用。

7:集合
集合是零个、一个或多个元组的有序集合。集合最常用于在 MDX 查询中定义轴维度和切片器维度,并且同样可能只具有单个元组或可能在某些情况下为空。下面的示例显示具有两个元组的集合:

{ (时间.[上半年], 路线.非陆地.航空), (时间.[下半年], 路线.非陆地.海路) }
一个集合可包含同一个元组不止一次的出现。下面的集合是可接受的:

{ 时间.[下半年], 时间.[下半年] }
集合指以元组表示的一组成员组合,或指集合中的元组所代表的单元中的值,视集合使用的上下文而定。

在 MDX 语法中,元组用花括号括起来以构造集合。


重要 由单个元组组成的集合不是元组;MDX 将其解释为集合。某些 MDX 函数接受元组作为参数,而如果传递单个元组集合,则会产生错误。元组和单个元组集合不可互换。

8:基本 MDX 查询
基本多维表达式 (MDX) 查询以与下面的示例类似的方式进行构造:

SELECT [<axis_specification>
[, <axis_specification>...]]
FROM [<cube_specification>]
[WHERE [<slicer_specification>]]
基本 MDX 语法——SELECT 语句

在 MDX 中,SELECT 语句用于指定包含多维数据的子集的数据集。为讨论 MDX SELECT 语句的各种语法元素,本主题提出一个基本 MDX 查询示例并将其分解为本身的各种语法元素以讨论各个元素的用途和结构。

若要指定数据集,MDX 查询必须包含有关下列各项的信息:

轴的数目。最多可在 MDX 查询中指定 128 个轴。
要包括在 MDX 查询的各个轴上的来自各个维度的成员。
设置 MDX 查询上下文的多维数据集的名称。
来自切片器维度的成员,在该维度上对来自轴维度的成员进行数据切片。
这些信息可能很复杂。如您在本主题中将看到的,MDX 语法可以简单且直观的方式使用 MDX SELECT 语句提供这类信息。

基本 MDX 查询示例

以下 MDX 查询示例用于讨论基本的 MDX SELECT 语句语法的各个部分:

SELECT
{ [Measures].[Unit Sales], [Measures].[Store Sales] } ON COLUMNS,
{ [Time].[1997], [Time].[1998] } ON ROWS
FROM Sales
WHERE ( [Store].[USA].[CA] )
9:DrilldownLevel
将集合的成员深化到集合中所表示的最低级别的下一级,或者深化到集合中所代表的一个任意指定的成员级别的下一级。

语法

DrilldownLevel(«Set»[, {«Level» | , «Index»}])

返回集合的按层次结构排列的成员,该集合在 Set 中指定,比集合中所表示的最低级别低一级,或者比通过Level 中的引用或通过 Index 中基于零的索引指定的任意级别低一级,是集合中所表示的一个成员。

示例

以例返回集合 {USA, CA, <all cities in CA>, WA, <all cities in WA>, Canada}:

DrilldownLevel({[Customers Location].USA, [Customers Location].CA,
[Customers Location].WA, [Customers Location].Canada})
  回复  更多评论
  

# re: 简介 2006-05-05 14:44 吴名居
6.1 概述
MDX( Multidimensional Expressions )是一种语法,支持多维对象与数据的定义和操作
MDX 在很多方面与结构化查询语言 (SQL) 语法相似,但它不是 SQL 语言的扩展;事实上,MDX 所提供的一些功能也可由 SQL 提供,尽管不是那么有效或直观。

每个 MDX 查询都要求有 SELECT 子句、FROM 子句和WHERE 。MDX 还提供了可靠的函数集,用来对所检索的数据进行操作,同时还具有用用户定义函数扩展 MDX 的能力。

MDX 提供管理数据结构的 DDL 语法,其中有用于创建(和删除)多维数据集、维度、度量值以及它们的坐标对象的 MDX 命令。
下面说明用于存储定单信息的传统关系数据库:
6.2 基本概念

对于多维数据,则可以用具有两个以上维的结构来表示。这些称作多维数据集的结构具有多个维度。

在多维数据集中维度的交集处,可能有不止一个数据元素,这些数据元素称为度量值。
6.2.1 单元、元组和集合
SQL 从表返回二维数据子集,而 MDX 从多维数据集返回多维数据子集。
以下元组标识其中值为 240 的单元:
路线(.[东半球].[非洲], 时间.[下半年].[第四季度], 源.[非陆地].[航空], 度量值.包 )

元组唯一标识多维数据集中的一部分;它不必指某个特定单元(切片)
(源.[东半球])
(时间.[下半年], 源.[西半球])

元组的有序集合称为集合
{ (时间.[上半年].[第一季度]), 时间.[下半年].[第三季度]) }
6.2.2 轴维度和切片器维度

SELECT 语句用来选择要返回的维度和成员,称之为轴维度。

WHERE 语句用来将返回的数据限定为特定维度和成员条件,称之为切片器维度。

轴维度预期返回多个成员的数据,而切片器维度预期返回单个成员的数据。
6.2.3 计算成员
计算成员不是基于数据、而是基于 MDX 中估值表达式的成员

6.2.4 用户定义函数
用户可以创建和注册自己的函数,这些函数对多维数据进行操作,同时按 MDX 语法接受参数并返回值。

6.2.5 PivotTable 服务
MDX 数据定义和操作服务通过 PivotTable 服务提供。
PivotTable 服务用于本地多维数据集的定义和操作,使用此多维数据集可以多维格式在本地存储数据。
6.3 SQL 和 MDX 比较

(1) 专门检索具有几乎任意多个维度的多维数据结构中的数据
(2) MDX 在查询中则可处理一个、两个、三个或更多的维度。
(3) 在 MDX 中 SELECT 子句可用于定义几个轴维度,而 WHERE 子句可用来多维数据限制于特定的维度或成员。
(4) WHERE 子句用于提供查询所返回的数据切片。
(5) WHERE 子句中的各个成员标识来自不同维度的数据的不同部分
(6) MDX 查询的创建者通常将多维数据集的结构形象化并加以定义,并且编写对单个多维数据集的查询对该结构进行填充
(7) MDX 结果集的视觉形象不直观。因为多维结果集可以有三个以上的维度,所以将该结构形象化比较困难
6.4 基本 MDX
6.4.1 基本 MDX 查询

SELECT [<axis_specification> [, <axis_specification>...]]
FROM [<cube_specification>]
[WHERE [<slicer_specification>]]

要指定数据集,MDX 查询必须包含有关下列各项的信息:

(1) 轴的数目。最多可在 MDX 查询中指定 128 个轴。

(2) 要包括在 MDX 查询的各个轴上的来自各个维度的成员。

(3) 设置 MDX 查询上下文的多维数据集的名称。

(4) 来自切片器维度的成员,在该维度上对来自轴维度的成员进行数据切片
基本 MDX 查询示例:


别名
SELECT
{ [Measures].[Unit Sales], [Measures].[Store Sales] } ON COLUMNS,
{ [Time].[1997], [Time].[1998] } ON ROWS
FROM Sales
WHERE ( [Store].[USA].[CA] )
MDX SELECT 语句的语法格式与 SQL 语法类似;可是用户将注意到以下几个显著区别:

(1) MDX 语法通过用花括号({ 和 } 字符)括住元组或成员来辨别集合。

(2) MDX 查询在 SELECT 语句中最多可以有 128 个轴维度,但只有前 5 个轴有别名。轴可以用其在 MDX 查询中的顺序位置或者用其别名(如果给它指派了别名的话)来引用。

SELECT
{ [Measures].[Unit Sales], [Measures].[Store Sales] } ON AXIS(0),
{ [Time].[1997], [Time].[1998] } ON AXIS(1)
FROM Sales WHERE ( [Store].[USA].[CA] )

(3) 如同 SQL 查询一样,FROM 子句为 MDX 查询指定数据的源

(4) WHERE 子句用于描述切片器维度。
  回复  更多评论
  

# re: 简介 2006-05-05 14:46 吴名居
6.4.2 成员、元组和集合
1. 成员
下图加入阴影以表示 “时间.[下半年].[第三季度]” 成员。
成员名和成员键:

引用成员的可选方法是引用成员键。成员键由维度用来专门标识给定成员。
成员键: 用 & 字符将成员键与成员名区别开

[时间].[下半年].&[Q4] ( "第四季度"成员的成员键 Q4)

引用成员键确保在可更改维度中以及在具有非唯一成员名的维度中成员的正确标识。

可用成员名或其成员键引用某个成员。上一示例中用其成员名 “第四季度” 引用 “时间” 维度中的成员
计算成员:

可将成员创建为 MDX 查询的一部分,以使返回的数据基于估值表达式,而不是要查询的多维数据集中所存储的数据,这些成员称为计算成员。

如以下示例所示:

WITH MEMBER [Measures].[PackagesForecast] AS
'[Measures].[Packages] * 1.1'
成员函数:

MDX 提供许多函数来从其它 MDX 实体(如维度和级别)检索成员

// FirstChild 函数允许从给定维度或级别检索所有的成员


// 下列两式具有相同效果

显式声明 : 时间.[上半年]
函数调用 : 时间.FirstChild // "时间"维度的第一个子代成员
2. 元组
元组用于定义来自多维数据集的数据切片;它由来自一个或多个维度的单个成员的有序集合组成。
元组用于标识来自多维数据集的特定多维数据块;元组是一种成员向量;请把元组看作基础数据库中的一个或多个记录
3. 集合
集合是零个、一个或多个元组的有序集合。集合最常用于在 MDX 查询中定义轴维度和切片器维度,并且可能只具有单个元组或可能在某些情况下为空。
集合指以元组表示的一组成员组合,或指集合中的元组所代表的单元中的值(视使用的上下文而定)
元组用花括号括起来以构造集合

示例

{ (时间.[上半年], 源.非陆地.航空), (时间.[下半年],源.非陆地.海路) }

{ 时间.[下半年], 时间.[下半年] } // 允许同一个元组重复出现
聚合函数

冒号运算符使用成员的自然顺序创建集合

两边的成员包含在结果集内:{[第一季度]:[第四季度]}



集合和维数

集合的维数用其中各个元组的维数表达。集合内元组的顺序非常重要

下例不能作为集合使用:集合中的元组必须具有相同的维数

{ (时间.[下半年],源.非陆地.航空), (源.非陆地.航空, 时间.[下半年]) }
6.4.3 轴维度和切片器维度

轴维度,为多个成员检索数据的维度。

切片器维度,为单个成员检索数据的维度。
  回复  更多评论
  

# re: 简介 2006-05-05 14:48 吴名居
1. 指定轴维度的内容

<axis_specification> 语法可分解为:

<axis_specification> ::= <set> ON <axis_name>

<axis_name> ::= COLUMNS | ROWS | PAGES | SECTIONS | CHAPTERS | AXIS(<index>)

每个轴维度与一个数字相关联:
0 对应于 x 轴,1 对应于 y 轴,2 对应于 z 轴,等等。
<index> 值是轴号。对于前 5 个轴,COLUMNS、ROWS、PAGES、SECTIONS 和 CHAPTERS 这几个别名可分别代替 AXIS(0)、AXIS(1)、AXIS(2)、AXIS(3) 和 AXIS(4) 使用。
2. 指定切片器维度的内容

(1)显式指派给轴的维度是切片器维度
(2)假定未显式指派给轴的维度是切片器维度,用其默认成员进行筛选。
(3)如果未显式指定默认成员,
如果存在“(全部)”级别,则默认成员为“全部”成员,
否则为最高级别的任意成员。("全部"成员的名称不必为"全部"。)
6.4.4 建立多维数据集上下文


MDX 查询提供上下文:

FROM <<cube_specification>>
<< cube_specification >> 由单个多维数据集的名称完成。

这并未限制用户一次使用多个多维数据集;可以使用 LookupCube 函数来从多维数据集上下文以外的多维数据集检索数据。

与 SQL 不同,MDX 查询中的 FROM 子句通常不允许联接:

FROM SalesCube, OtherCube
6.5 高级 MDX
6.5.1 创建和使用属性值

1. 成员属性的使用
各个元组中每个成员的一些基本信息,如成员名、父级别、子代数目等等。这些信息即称为成员属性。成员属性可视为存储于单个维度上按维度组织的数据。

例如,若要创建 Store Name 级别中成员的成员属性 Store Type,须确保 Store Type 列与 Store Name 列在相同的表中,然后将 Store Type 作为成员属性插入到 Store Name 级别中。

(1) DIMENSION PROPERTIES 关键字

SELECT [<axis_specification> [, <axis_specification>...]]
FROM [<cube_specification>]
[WHERE [<slicer_specification>]]

<axis_specification> ::= <set> [<dim_props>] ON <axis_name>

<dim_props> ::= [DIMENSION] PROPERTIES <property> [,<property>...]

property 语法的分解会因所查询的属性而有所不同。维度和级别的内在成员属性前必须加上维度和/或级别的名称。
成员的内在成员属性不能由维度名或级别名限定。自定义成员属性前应加上其所驻留的级别的名称。
例:

SELECT //Members 函数是最常用的集合函数之一,
//返回维度、级别或层次结构中成员的集合

CROSSJOIN(年, (销售量, 预算销售量)) ON COLUMNS,
NON EMPTY 产品.MEMBERS // 关键字,非空
DIMENSION PROPERTIES 产品.SKU, 产品.SRP ON ROWS
FROM SalesCube
WHERE (一月, 销售代表.[All], 地理.美国)

返回以下数据集:
(2) Properties 函数

成员属性还可通过使用 MDX 中的 Properties 函数进行检索。例如,下面的 MDX 查询使用 WITH 关键字来创建包含 [Store Sqft] 成员属性的计算成员:

WITH // 生成计算成员
MEMBER [度量值].[商店规模] AS
‘Val(商店.当前成员.属性(“商店平方米”))’ //VB库中的函数


SELECT
{[度量值].[单个销售额], [度量值].[商店规模]} ON COLUMNS,
{[商店].[商店名称].成员} ON ROWS
From Sales
请注意 MDX 查询示例中 Val( ) 函数的使用。Properties 函数是字符串类型的函数;所有用 Properties 函数检索的成员属性均将强制转换为字符串。
(3) 内在维度和级别成员属性

所有维度和级别均支持下表所列的内在成员属性。这些成员属性在特定维度或级别的上下文中使用,并且为指定维度或级别的每个成员提供值。例如,在多维表达式 (MDX) 查询中指定下列语句:

[Sales].Name //返回级别、维度、成员或层次结构的名称

返回 [Sales] 维度的各个引用成员的名称:


属性 描述
ID 成员的内部维护 ID
Key 存储于 MEMBERS 架构行集的 MEMBER_KEY 列中
成员的值
Name 成员的名称   回复  更多评论
  

# re: 简介 2006-05-05 14:49 吴名居
维度成员属性前是应用属性的维度的名称

下例示范了正确的语法:

DIMENSION PROPERTIES <<Dimension>>.ID

级别成员属性前可加上级别名,或为附加规范加上维度和级别名,如下所示:

DIMENSION PROPERTIES [<<Dimension>>.]<<Level>>.ID
4) 内在成员属性
内在成员属性不能为特定维度或级别加以请求,而应用于多维表达式 (MDX) 查询中轴维度的所有成员

例如,在 MDX 查询中指定下列语句:

PROPERTIES DESCRIPTION

返回对轴维度中各个成员的描述。
下表列出所支持的内在成员属性:

属性 : 描述

CALCULATION_PASS_DEPTH: 仅用于计算单元。计算公式的传递深度,此属性确定解析计算公式需要多少个传递。有关传递次序的更多信息,请参见理解传递次序和求解次序。

CALCULATION_PASS_NUMBER: 仅用于计算单元。计算公式的传递号,此属性确定计算公式将分别在哪个传递上开始赋值和结束计算。该属性的默认值为 1;其最大值为 65,535。有关传递次序的更多信息,请参见理解传递次序和求解次序。
  回复  更多评论
  

# re: 简介 2006-05-05 14:51 吴名居
(5) 自定义成员属性

自定义成员属性可添加到维度中的特定命名级别中。自定义成员属性不能添加到维度的“(全部)”级别,或添加到维度本身

用来引用自定义成员属性的语法类似于用来引用内在级别成员属性的语法,如下列示例所示:

PROPERTIES [<Dimension>.]<Level>.<Custom Member Property>
2. 单元属性的使用

MDX 单元属性所包含的信息,是单元的内容和格式的信息。

下例显示 MDX SELECT CELL PROPERTIES 关键字语法。

SELECT [<axis_specification> [, <axis_specification>...]]
FROM [<cube_specification>]
[WHERE [<slicer_specification>]]
[<cell_props>]

<cell_props> ::= CELL PROPERTIES <property> [, <property>...]
下表列出用于 <property> 值的受支持内在单元属性

属性 描述

BACK_COLOR: 显示 VALUE 或 FORMATTED_VALUE 属性的背景颜色。有关更多信息,请参见 FORE_COLOR 和 BACK_COLOR 内容。

CELL_EVALUATION_LIST: 适用于单元的以分号分隔的一列求值公式,按从最低到最高的求解次序排列。有关求解次序的更多信息,请参见理解传递次序和求解次序。

CELL_ORDINAL 数据集中单元的序列号。

FORE_COLOR: 显示 VALUE 或 FORMATTED_VALUE 属性的前景颜色。有关更多信息,请参见 FORE_COLOR 和 BACK_COLOR 内容。
默认情况下,如果未用 CELL PROPERTIES 关键字,则返回的单元属性为 VALUE、FORMATTED_VALUE 和 CELL_ORDINAL(按此顺序)。
如果使用了 CELL PROPERTIES 关键字,则只返回用此关键字显式声明的单元属性。

下例示范了 MDX 查询中 CELL PROPERTIES 关键字的使用:

SELECT
{[Measures].[Unit Sales], [Measures].[Store Size]} ON COLUMNS,
{[Store].[Store Name].Members} ON ROWS
FROM Sales
CELL PROPERTIES VALUE, FORMATTED_VALUE, FORMAT_STRING, FORE_COLOR, BACK_COLOR
3. 使用 Custom Member Options 属性

使用维度编辑器或多维数据集编辑器的 Custom Member Options 属性,可通过 Analysis Manager 设置单元属性。

Custom Member Options 属性接受每个成员的列引用,该引用包含以逗号分隔的单元属性列表。

单元属性以字符串表达式的形式表示,如例所示。

FORE_COLOR='255', BACK_COLOR='65535'

示例为指定成员提供一个带红色前景的黄色背景。
4. 使用 FORMAT_STRING 单元属性


FORMAT_STRING 单元属性用于格式化 VALUE 单元属性,以创建 FORMATTED_VALUE 单元属性值。

FORMAT_STRING 单元属性对于字符串和数字原始值均能处理,它对该值应用格式表达式以返回 FORMATTED_VALUE 单元属性的格式化值。
5. 使用字符串值符号

字符串的格式表达式可以是一部分,也可以是由分号 (;) 分隔开的两部分。

一部分格式应用于所有字符串值。

两部分时第一部分应用于字符串数据,而第二部分应用于空值和零长度字符串 ("")。



(1)@ 字符占位符。它显示一个字符或一个空格。
(2)& 字符占位符。它显示一个字符或什么都不显示。
(3)< 强制小写。以小写格式显示所有字符。
(4)> 强制大写。以大写格式显示所有字符。
(5) ! 强制从左到右填充占位符。
6. 使用数字值

数字的用户定义格式表达式可以有一到四个由分号分隔的部分。如果格式参数包含一个命名数字格式,则只允许有一个部分。

一部分:格式表达式应用于所有值。
两部分:第一部分应用于正值和零,第二部分应用于负值。
三部分: 第一部分应用于正值,第二部分应用于负值,第三部分应用于零。
四部分:第一部分应用于正值,第二部分应用于负值,第三部分应用于零,第四部分应用于空值。

下例具有两个部分:"$#,##0;($#,##0)"

如果包含两个紧挨着的分号,则缺少的部分用正值的格式打印。
"$#,##0;;\Z\e\r\o"

7. 使用 FORE_COLOR 和 BACK_COLOR 单元属性

以 Microsoft Windows 操作系统红-绿-蓝 (RGB) 格式存储单元的文本和背景的颜色信息。

范围为 0 到 16,777,215 (&H00FFFFFF)

数字的高位字节始终等于 0;低位的 3 个字节,从最低位字节到最高位字节分别决定了红色、绿色和蓝色的数量。红色、绿色和蓝色成分分别由一个 0 到 255 (&HFF) 之间的数字表示。

例如,值 255 (&H000000FF) 代表红色,值 65280 (&H0000FF00) 代表绿色,而值 16711680 (&H00FF0000) 代表
6.5.2 生成 MDX 中的命名集
MDX 中的集可能是长而复杂并且不易理解的声明
(参阅 p163 式子)
命名集是一个与别名相关联的集合表达式。命名集可将集合中的成员或函数合并。

命名集是维度成员集或所创建的可以再度使用的集合表达式。

WITH SET [ChardonnayChablis] AS
'{[Product].[All ……..
…………..
SELECT
[ChardonnayChablis] ON COLUMNS,
{Measures.[Unit Sales]} ON ROWS
FROM Sales
使用 WITH 创建命名集

[WITH <formula_specification>] [, formula_specification>]
SELECT [<axis_specification> [, <axis_specification>...]]
FROM [<cube_specification>]
[WHERE [<slicer_specification>]]

<formula_specification> ::= SET <set_name> AS '<set>'

<set_name> 参数包含命名集的别名。
<set> 参数包含命名集别名所指的集合表达式。
示例使用 Filter、CurrentMember、Name 和 InStr 函数来创建 [ChardonnayChablis] 命名集:
// VB:InStr ([start, ] string1, string2 [, compare])
//返回:指定一字符串在另一字符串中最先出现的位置。
// CurrentMember: MDX 表达式,拒绝对度量值“ chardonnay ”
//的单元的访问,但允许对所有其它度量值的单元的访问
// Filter(«Set», «Search Condition»)
//返回根据搜索条件对指定集合进行筛选所得到的集合。
WITH SET [ChardonnayChablis] AS
'Filter([Product].Members, (InStr(1, [Product].CurrentMember.Name, "chardonnay") <> 0) OR (InStr(1, [Product].CurrentMember.Name, "chablis") <> 0))'

SELECT
[ChardonnayChablis] ON COLUMNS,
{Measures.[Unit Sales]} ON ROWS
FROM Sales
6.5.3 生成 MDX 中的计算成员
1. 使用 WITH 创建计算成员

[WITH <formula_specification>] [, <formula_specification>]
SELECT [<axis_specification> [, <axis_specification>...]]
FROM [<cube_specification>]
[WHERE [<slicer_specification>]]

<formula_specification> ::= MEMBER <member_name>
AS '<value_expression>'
[,SOLVE_ORDER = <unsigned integer>]
[,<cell_property> = <value_expression>...]

(1)<member_name> 值是计算成员的完全合法名称, <value_expression> 在经过计算后,将返回计算成员的值。
(2)使用 SOLVE_ORDER 关键字指定计算成员的求解次序
(3)<cell_property> 值中提供单元属性的名称和在 <value_expression> 值中提供单元属性值,可随意指定计算成员内在单元属性的值  回复  更多评论
  

# re: 简介 2006-05-05 14:53 吴名居
下例的 MDX 查询示例定义了两个计算成员。第一个计算成员 [Measures].[StoreType] 用于表示 Store Type 成员属性。第二个计算成员 [Measures].[ProfitPct] 用于计算给定商店的总利润率,并将其表示为格式化的百分比值。

WITH
MEMBER [Measures].[StoreType] AS
'[Store].CurrentMember.Properties("Store Type")',
SOLVE_ORDER = 2
MEMBER [Measures].[ProfitPct] AS
'Val((Measures.[Store Sales] - Measures.[Store Cost]) /
Measures.[Store Sales])',
SOLVE_ORDER = 1, FORMAT_STRING = 'Percent'
SELECT
{ [Store].[Store Name].Members} ON COLUMNS,
{ [Measures].[Store Sales], [Measures].[Store Cost],
[Measures].[StoreType], [Measures].[ProfitPct] } ON ROWS
FROM Sales
计算成员可在层次结构的任意位置创建。

下例 MDX 查询示例定义作为 [Beer and Wine] 成员的子成员创建的计算成员,以确定给定商店的啤酒和果酒 (Beer and Wine) 的单位销售额是否至少为 100.00:


WITH
MEMBER [Product].[Beer and Wine].[BigSeller] AS
'IIf([Product].[Beer and Wine] > 100, "Yes","No")’

SELECT
{[Product].[BigSeller]} ON COLUMNS,
{Store.[Store Name].Members} ON ROWS
FROM Sales

使用同一 MDX 中其它计算成员的计算成员:

WITH
MEMBER [Measures].[ProfitPct] AS
'Val((Measures.[Store Sales] - Measures.[Store Cost]) /
Measures.[Store Sales])',
SOLVE_ORDER = 1, FORMAT_STRING = 'Percent'
MEMBER [Measures].[ProfitValue] AS
'[Measures].[Store Sales] * [Measures].[ProfitPct]',
SOLVE_ORDER = 2, FORMAT_STRING = 'Currency'
SELECT
{ [Store].[Store Name].Members} ON COLUMNS,
{ [Measures].[Store Sales], [Measures].[Store Cost],
[Measures].[ProfitValue], [Measures].[ProfitPct] } ON ROWS
FROM Sales

第二个计算成员 [Measures].[ProfitValue] 使用第一个计算成员 [Measures].[ProfitPct] 中创建的值来生成自己的值。
2. 在计算成员中使用函数

(1) 算术运算符: + , - , * , /
(2) 比较运算符: > , < , >= , <= , < > , =
(3) 按位运算符: AND , OR , NOT , XOR (与 C 相同)
(4) 集合运算符:
<<Set1>> + <<Set1>> 对两个集合执行 Union 函数。
<<Set1>> * <<Set2>> 对两个集合执行 Crossjoin 函数。
<<Set1>> - << Set2>> 对两个集合执行 Except 函数。
<<Member1>> : <<Member2>> 创建自然排序集合,并将两个成员作为终结点,这两个指定成员间的所有成员作为集合的成员包括其中。
5)数值函数

如下面的 MDX 查询示例所示,当 Aggregate 函数与产生总和的度量值相组合时,功能尤其强大:

WITH
MEMBER [Time].[1st Half Sales] AS 'Aggregate({Time.[Q1], Time.[Q2]})'
MEMBER [Time].[2nd Half Sales] AS 'Aggregate({Time.[Q3], Time.[Q4]})',
MEMBER [Time].[Difference] AS 'Time.[2nd Half Sales] - Time.[1st Half Sales]',
SELECT
{ [Store].[Store State].Members} ON COLUMNS,
{ Time.[1st Half Sales], Time.[2nd Half Sales], Time.Difference} ON ROWS
FROM Sales
WHERE [Measures].[Store Sales]

查询产生了各州的店面销售额总和,带有前两个计算成员用 Aggregate 函数所提供的上半年和下半年的聚合,以及由第三个计算成员提供的二者的差额。
MDX 还提供了一列统计函数,以处理例程统计计算,例如,Median 函数计算集合内的中值,以下 MDX 查询:

WITH
MEMBER [Time].[1st Half Sales] AS 'Sum({[Time].[Q1], [Time].[Q2]})'
MEMBER [Time].[2nd Half Sales] AS 'Sum({[Time].[Q3], [Time].[Q4]})'
MEMBER [Time].[Median] AS 'Median(Time.Members)'
SELECT
NON EMPTY { [Store].[Store Name].Members} ON COLUMNS,
{ [Time].[1st Half Sales], [Time].[2nd Half Sales], [Time].[Median]} ON ROWS
FROM Sales
WHERE [Measures].[Store Sales]

在本示例中,除了 [Time].[1st Half Sales] 和 [Time].[2nd Half Sales] 计算成员提供的各个商店的上半年和下半年的店面销售额的聚合之外,还有 [Time].[Median] 计算成员提供的各个商店店面销售额的中值。
6) 字符串函数


MDX 提供许多字符串函数,不只是为了 MDX 表达式内的字符串处理,还为了支持 MDX 中用户定义函数。

例如,MemberToStr 函数将某成员引用转换为 MDX 格式的字符串以用于用户定义函数,因为用户定义函数不接受来自 MDX 的对象引用。
(7)集合函数

集合函数用于在 MDX 中返回集合,为用户提供方便生成动态定义的集合和快速创建可再次使用的命名集的功能。
Members 函数是最常用的集合函数之一,它将级别或维度的所有成员(计算成员除外)作为一个集合返回。
下面的 MDX 查询示例示范了工作中的 Members 函数。

SELECT
NON EMPTY { [Store].[Store Name].Members} ON COLUMNS,
{Measures.[Store Sales]} ON ROWS
FROM Sales

本 MDX 查询示例返回了 Sales 多维数据集中的各个商店的总销售额数字。如果不用 Members 函数,则不得不显式输入各个商店名称,以使其完成本 MDX 查询示例的功能。
(8) 元组函数


如同集合函数,元组函数用于在 MDX 中返回元组。元组函数还用于辅助 MDX 中的用户定义函数,如 StrToTuple 函数。

由于用户定义函数不能处理 MDX 对象引用,用户定义函数可以返回 MDX 格式的字符串返回值来表示元组,并使用 StrToTuple 函数将它转换为有效的元组引用。
(9) 成员函数

计算成员中常常引用成员;成员函数允许计算成员执行复杂成员检索,从而同样轻松地处理层次结构和集合。

MDX 中计算成员的解可以是本质上迭代的,因为计算成员可以基于对集合成员的迭代进行构造。MDX 中 CurrentMember 之类的函数使您得以利用此迭代功能
(10) IIf 函数

多维表达式 (MDX) 中的 IIf 函数可用于执行简单的是或否决策。下例 MDX 查询示例:

WITH MEMBER [Measures].[BigSeller] AS
'IIf(Measures.[Store Sales] > 20000, "Yes", "No")'


SELECT
{[Store].[Store Name].Members} ON COLUMNS,
{[Measures].[Store Sales], [Measures].[BigSeller]} ON ROWS
FROM Sales

本 MDX 示例返回两行。一行是 [Measures].[Store Sales] 成员,提供各个商店的总销售额。第二行是一个计算成员,它基于各个商店的销售额决定商店是否是个"大销售商"。
  回复  更多评论
  

# re: 简介 2006-05-05 14:54 吴名居
6.5.4 生成 MDX 中的高速缓存

MDX 常用多维数据集切片装载到内存,对其进行高速缓存以达到更快检索的目的。

(1) 可使用 CREATE CACHE 语句。
(2) WITH 语句也可完成这项任务。

例如,下面的 MDX 查询使用 WITH 语句来进行高速缓存:

WITH CACHE AS '(Store.[Store Name].Members)'

SELECT
{[Store].[Store Name].Members} ON COLUMNS,
{[Measures].[Unit Sales]} ON ROWS
FROM Sales
使用 WITH 创建高速缓存

[WITH <formula_specification>] [, <formula_specification>]
SELECT [<axis_specification> [, <axis_specification>...]]
FROM [<cube_specification>]
[WHERE [<slicer_specification>]]

高速缓存的 <formula_specification> 值进一步分解:

<formula_specification> ::= CACHE AS '(<set>[, <set>...])'

(1) <set> 值是用来创建高速缓存的集合表达式。<set> 值可支持 MDX 集合函数的使用。
(2) 当用 <set> 集合表达式构造高速缓存时,下列规则适用:
(a) 每个 <set> 都必须包含仅来自一个维度的成员。各个成员必须互不相同。
(b) 各个 <set> 必须来自不同的维度。
(c) <set> 不能包含度量值。
6.5.5 生成 MDX 中的计算单元
计算单元功能通过使您得以定义单元的特定切片(称为计算子多维数据集),并将公式应用到该计算子多维数据集内的各个单元来提供此功能。应用公式时,依据的是可应用于每个单元的可选条件。
计算成员是维度成员,其值于运行时通过在定义计算成员时所指定的表达式计算而得到。

(1) 使用 CREATE CELL CALCULATION 语句。对于现有多维数据集,ALTER CUBE 语句也可用来添加计算单元。

(2) 若要创建用于会话生存周期的计算单元,请使用 CREATE CELL CALCULATION 语句。

(3) 若要创建用于查询生存周期的计算单元,请使用 WITH 语句
使用 WITH 创建计算单元

[WITH <formula_specification>] [, <formula_specification>]
SELECT [<axis_specification> [, <axis_specification>...]]
FROM [<cube_specification>]
[WHERE [<slicer_specification>]]

<formula_specification> ::= CELL CALCULATION <formula_name>
FOR '(<calculation_subcube>)'
AS '<calculation_formula>' [,<calculation_property_list>]

<cell_property_list> ::= <property_name = '<value>’
[, <property_name> = '<value>'...]

<formula_name> 值是计算单元的名称。<calculation_subcube> 包含一列正交的、单维度 MDX 集合表达式,而每个表达式都必须解析为下列集合分类之一:
分类 描述 :


空集合:解析为空集合的 MDX 集合表达式。在这种情况下,该集合被忽略。

单个成员集合:解析为单个成员的 MDX 集合表达式。

级别成员的集合:解析为单个级别的成员的 MDX 集合表达式。其示例为 <<Level>>.Members MDX 函数。若要包括计算成员,请使用 <<Level>>.AllMembers MDX 函数。

后代的集合:解析为指定成员后代的 MDX 集合表达式。其示例为 Descendants(<<Member>>, <<Level>>, <<Desc_flags>>) MDX 函数。
补充考虑事项:

CONDITION 属性指定的计算条件根据计算单元定义的创建范围只处理一次。这提高了赋值多个计算单元定义的性能,尤其是多维数据集传递间具有重叠的计算单元的情况。

如果计算条件在全局范围内作为多维数据集的一部分创建,则在处理多维数据集时处理计算条件。如果以任何方式在多维数据集中修改了单元,而且单元包括在计算单元定义的计算子多维数据集中,则在重新处理该多维数据集前,该计算条件可能不准确。

如果计算条件在会话范围创建,则在会话中发出该语句时对计算条件进行处理。与全局创建的计算单元定义一样,如果修改单元,则计算条件对于计算单元定义可能不准确。

如果计算条件在查询范围创建,则在执行查询时对计算条件进行处理。虽然 MDX 查询执行的处理时间短,数据滞后时间问题充其量是极轻微的,但单元修改问题在这里同样存在。

另一方面,只要对包含单元(这些单元包含在计算单元定义中)的多维数据集发出 MDX 查询,就会处理计算公式,而与范围无关。
  回复  更多评论
  

# re: 简介 2006-05-05 14:57 吴名居
6.5.6 在 MDX 中创建和使用用户定义函数


1. 在 MDX 中使用用户定义函数:

无参数调用:
MyNewFunction( )

有参数调用:
MyNewFunctionWithParms("Parameter1", 2, 800)

2. USE LIBRARY 语句:

用 USE LIBRARY 语句执行外部库的装载。
用户定义函数都必须与 COM 类相关联,这些类通常以 Microsoft ActiveX 动态链接库 (DLL) 的形式提供。

假如用户定义函数位于 C:\Winnt\System 、名为 MyFunc.dll 的 ActiveX DLL 的一部分,可将其装载如下:
USE LIBRARY "C:\WINNT\SYSTEM\MyFunc.dll"

与 "MyFuncClass"类关联,可装载库:
USE LIBRARY "MyFunc.MyFuncClass"

当引用可能位于不同服务器的不同位置的库时,推荐使用本方法。

多个库可以用单个 USE LIBRARY 语句同时装载:
USE LIBRARY "C:\WINNT\SYSTEM\MyFunc.dll", "C:\WINNT\SYSTEM\NewFuncs.dll"

不带参数的 USE LIBRARY 语句将注消所有函数库。
3. DROP LIBRARY 语句


DROP LIBRARY 语句可用于卸载特定库或卸载所有的库:

DROP LIBRARY "MyFunc.MyFuncClass"

PivotTable 服务支持 DROP LIBRARY 语句。
4. 创建用户定义函数

用户定义函数可用支持 COM 接口的任何编程语言创建

用户定义函数可接受任何可强制转换为字符串、数字或者字符串数组或数字数组的参数。

用户定义类型或对象引用不能用作参数。

数组也可用作参数

返回空值的函数(例如 Visual Basic 中的子程序)也可使用,例如,如果想要在 MDX 语句中使用 MyVoidFunction() 函数,可采用下面的语法:

CALL(MyVoidFunction)
6.5.7 使用回写

将信息写入到多维表达式 (MDX) 中的写启用多维数据集的功能称为回写。

1. 最低级别成员回写

最低级别成员指维度中与该维度最低定义级别相关联的成员。例如,下图中,Products(产品)维度定义了三个级别("(全部)"级别不算在内)
2. 聚合级别成员回写

聚合级别成员的值取决于与聚合级别以下级别相关的成员的值。例如,商标名称级别即是聚合级别,因为其成员的值取决于在产品名称级别上执行的聚合。

为了修改聚合级别,所有用于为该聚合级别而构造该值的成员都必须进行修改,所以聚合级别回写更难于处理。

可以使用 UPDATE CUBE 语句。通过使用四个不同的分配公式之一。聚合级别回写只有在使用 Sum 聚合函数聚合值时才能使用。

聚合级别回写尤其有用。聚合级别回写速度更快,因为将其视为单个原子事务进行处理,确保了安全性验证或公式验证不会使多维数据集处于不一致的状态。
6.5.8 使用 DRILLTHROUGH 检索源数据
DRILLTHROUGH 语句从源数据中检索行集。(钻取)

可以使用 AllowDrillThrough 和 DrillthroughColumns 属性

以下语法结构描述了 DRILLTHROUGH 语句:

<drillthrough> := DRILLTHROUGH [<Max_Rows>] [<First_Rowset>] <MDX select>

< Max_Rows> := MAXROWS <positive number>

(<max_rows> 语法指定各个返回行集中行的最大个数)

<First_Rowset> := FIRSTROWSET <positive number>

(<first_rowset> 语法标识其行集最先返回的分区)
下面的示例说明了 DRILLTHROUGH 语句的使用:

DRILLTHROUGH
SELECT [Warehouse].[All Warehouses].[Canada].[BC] ON ROWS,
[Time].[1998].[Q1] ON COLUMNS,
[Product].[All Products].[Drink] ON PAGES,
[Measures].[Units Shipped] ON SECTIONS
FROM [My Cube]
6.5.9 理解传递次序和求解次序
1.传递次序
当 MDX 为查询结果进行计算时,它至少要经过一个阶段的计算,每一阶段都称为一个计算传递,
可用顺序位置(称为计算传递号)对计算传递进行引用。

完全计算所有单元所需的计算传递的计数称为多维数据集的计算传递深度。
始终有一个计算传递,用来检索为多维数据集存储的数据,称为计算传递 0。
包含自定义汇总公式或自定义汇总计算,称计算传递 1
计算单元才会有大于 1 的计算传递号

传递关系图 传递描述
计算传递 3
因为带红色阴影的计算单元定义的 CALCULATION_PASS_DEPTH 为 2,所以再次对单元进行递归计算,所用的是从上一计算传递派生的值。在此传递中也再次对计算成员和自定义汇总公式进行计算。

计算传递 2
对两个计算单元定义的计算都根据 CALCULATION_PASS_NUMBER 和 CALCULATION_PASS_DEPTH 的取值从此处开始。在此传递中也再次对计算成员和自定义汇总公式进行计算。

计算传递 1
所有自定义汇总公式和自定义汇总运算符都在传递 1 上开始计算。

计算传递 0
从源检索数据。计算计算成员和自定义成员。此时不执行其它计算。
6.6 有效应用 MDX
6.6.1 MDX 中的注释


// C++ 风格的正斜线。

-- SQL 风格的连字符。

/*...*/ C 风格的正斜线与星号对。
示例说明 MDX 命令中注释的使用:

/* Using this query to view
info about units shipped
and units ordered */

WITH MEMBER [Measures].[ShippingPercent] AS
'-- Returns [Units Shipped] over [Units Ordered] as a percent value
Measures.[Units Shipped] / Measures.[Units Ordered]',
FORMAT_STRING = 'Percent'

SELECT
{ [Measures].[Units Shipped], [Measures].[Units Ordered], [Measures].[ShippingPercent] } ON COLUMNS,
// The next command specifies nonempty members only
NON EMPTY [Store].[Store Name].Members ON ROWS
FROM Warehouse -- Pulled from the Warehouse cube

注释加入了信息,但却不影响性能。
  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: