MDX 的全称是 Mutil Dimensional Expressions ,是由 Microsoft , Hyperion 等公司研究多维查询表达式,是所有 OLAP 高级分析所采用的核心查询语言。
MDX 可以用来进行以下操作:
1. calculated members (计算成员)
2. Calculated Cells (计算单元)
3. Security Settion (安全设置)
4. Custom member formula ( 自定义函数 )
5. Custom level rollup ()
6. Actions (动作)
7. Named “ sets ” ( 命名集合 )
8. Server side formatting (服务器数据格式化)
MDX 的基本结构有三种: Members 、 Tuple 、 Set 。
1. Members :指的是维度树上的一个节点,这里有一点需要指出,量度也是一个特殊的维度,所以对于普通维度上的 Member 可以有几下几种表示方法: [Customer] 或 [Time].[1996] 等,对于特殊的维度——量度而言,也可以表示一个 Member ,如: [Measures].[ unit sales] 等。
Member 的表示方法就是用中括号的形式,“ [……] ”。
2. Tuple :是由若干个 Members 组成,每一个维度上最多只能有一个 Member ,对于一个 Tuple 而言至少有一个维度,多则不限,同时对于没有列出来的那就表示为默认的 Member 。 Tuple 的表示方法是小括号“ () ”,因为其又有 Member 构成,所以通常的格式为“ ([…],[…][…],…) ”;示例:
a) ([Regin ].[USA])
b) ([product].[ computers],[time].[2008]) 。
3. Sets :同一维度上若干个 Members 的集合,或者是若干个 Tuples 的集合,但这里有一个地方需要注意,那就是如果是若干个 Tuple 组成的集合是,各个 Tuple 里的 Member 之间存在着一定的对应关系。集合的表示方法用大括号“ {} ”,所以可能的表示方法为:
a) {[time].[2008],[time].[2009],[time].[2000]} ,这里 Set 是由同一维度的若干个 Member 组成。
b) {([computer],[usa ]),([ mobile],[china])} ,这个 Set 是由两个 Tuples 组成,这里大家可以看到,在第一个 Tuple 当中,第一个 Member 是名为 computer 的产品,所以后面的 Tuple 的第一个 Member 也必须是一个产品,所以我们这里看到的是 mobile ,第一个 Tuple 里第二个 Member 是一个国家,所以第二个 Tuple 的第二个 Member 也必须是一个国家名,依次类推。
一个标准的 MDX 查询语句就是由我们前面介绍的 MDX 的三个基本对象构成,也就是 Member 、 Tuple 、 Set 。
一个标准的 MDX 查询的语法如下:
SELECT Set ON COLUMNS,
Set ON ROWS
FROM Cube
WHERE Tuple
示例:
SELECT
{[time].[ 1997],[time].[1998]}
ON COLUMNS,
{([product].[drink],[customer].[gender].[F]),( [product].[food],[customer].[gender].[M])}
ON ROWS
FROM
[Sales]
WHERE
([Measures].[ StoreSales ])
这个 MDX 查询就表示:查询时间为 1997 和 1998 两年的 drink 类产品,女消费者和 food 类产品男消费者的 Store Sales 。
它的作用是列出指定分类下的所有项,如
1. [product type].[food].children ,这就表示列出产品类型为 food 的所有产品。
2. [region ].[country].children ,这就表示列出所有的国家名称。
该函数不能用在 Tuple 中
当前某个 Member ,举例:
某个产品销售额贡献度计算,对于某一个产品或一种类型的产品而言它的销售额贡献度指的是它的销售额与所有产品销售额的比值,此时,如果我们要用 MDX 来计算这个贡献度的值是可以采用 CurrentMember 来实现,如:
此时我们的 MDX 表达可以是:
([product].currentMember ,[ Measures].[stores sales]) / ([product].[ all products],[Measures].[stores sales])
同时因为默认情况下指的就是 currentMember ,所以上面的 currentMember 可以去掉:
([Measures].[ stores sales]) / ([product].[ all products],[Measures].[stores sales])
所有 MDX 表达式的写法是由若干个 Tuple 组成 ,比如上面的这个表达式就是由两个 Tuple 的相除构成。
这两个元素分别指的是当前 Member 的上一个 Member 和当前 Member 的下一个 Member 。
利用这两个元素我们可以来实现实际当中常见的同期比(前期比),所谓的同期比指的 是:
(当前 member- 当前 member 的前一个 member ) / 当前 member 的前一个 member
对应到 MDX 表达式我们可以用 prevMember 和 nextMember 来实现,如:
(([time].currentMember ,[ Measures].[store sales])-([time].prevMember ,[Measures].[storessales ]))
/
([time].prevMember ,[ Measures].[store sales])
当然因为 currentMember 可以省略,所以上面的写法也可以是:
(([ Measures ].[store sales])-([time].prevMember ,[Measures].[storessales ]))
/
([time].prevMember ,[ Measures].[store sales])
下面的这张图就显示一个树
这张图中 all 这个节点是 97 和 98 的 parents , 97 和 98 也是 all 的 children ,同时 97 是 all 的 firstChild
如果我们要取到 97 下的所有的月份,那么我们就需要用 Descendants 来实现,它的语法是:
Descendants( [time].[97],month) ,这里的 month 是一个 level 的名称。所有它的格式为: Descendants([ 一个 Member], 一个 level 的名称 )
比如在食品销售当中,我们要知道哪一类的食品更受消费者欢迎,这样我们需要只知道各类食品的销量,比如食物( food )、饮料 (drink) 等的具体销量 (unit sales) ,然后再计算出所有食品总的销量( total sales ) , 如果采用 MDX 我们可以很容易的实现,采用 MDX 后的计算哪种食品更受欢迎的表达式如下:
([food].currentMember ,[ Measures].[unit sales])
/
([food].currentMember.parent ,[ Measures].[total sales])
因为 currentMember 可以省略,所以上面的写法又可以是:
( [ Measures].[unit sales])
/
([food].currentMember.parent ,[ Measures].[total sales])
未完待续 ……