1 MDX 简介
多维表达式 (MDX) 是用于在 多维数据库(olap)中处理和检索多维数据的查询语言。MDX 利用由标识符、值、语句、函数和运算符组成的表达式,计算结果可以检索对象 (,例如集或成员) ,或者 (标量值,例如字符串或数字) 。
MDX 查询和表达式用于执行以下操作:
- 从SQL Server SQL Server Analysis Services多维数据集将数据返回到客户端应用程序。
- 设置查询结果的格式。
- 执行多维数据集设计任务,包括定义计算成员、命名集、范围分配和关键绩效指标(KPI)。
- 执行管理任务,包括维度和单元安全性。
MDX 在很多方面与关系数据库常用的 SQL 语法看起来很相似。 但是,MDX 并非 SQL 语言的扩展,在许多方面都有别于 SQL。 为了创建用于设计或保护多维数据集的 MDX 表达式,或创建 MDX 查询以返回多维数据并设置其格式,您需要了解有关 MDX 和维度建模的基本概念、MDX 语法元素、MDX 运算符、MDX 语句以及 MDX 函数。
2 MDX 中的重要概念
在使用多维表达式 (MDX) 查询多维数据或创建多维数据集中的 MDX 表达式之前,有必要了解多维的概念和术语。
最好从已了解的数据汇总示例开始,然后查看 MDX 如何与之相关。 下面是在 smartbi 中创建的透视分析,其中填充了 “订单模型” 示例数据模型中的数据。
数据模型中包含度量值、维度和,所有这些在透视分析示例中都显而易见。
度量值 是事实表的数据列聚合为总和、计数、百分比、最小值、最大值或平均值的数值数据值。 在本示例中,单元格显示的“销售额”。 对于“订单日期”和“发货区域”的任意组合,都可获得为特定上下文求和的“销售额”。
维度 位于透视分析的列和行轴上,提供度量值背后的含义。 维度类似于关系数据模型中的表。 维度的常见示例包括“时间”、“区域”、“产品”、“客户”和“员工”等。 此示例包含两个维度,即行上的“发货区域”和横跨顶部的“订单日期”,但可以很容易地拖放与“销售额”关联的其他维度(例如“产品名称”或“公司类型”),从而按这些维度查看销售业绩。 以有趣的方式浏览数据的能力取决于创建的维度,以及这些维度是否与数据源中的事实数据表相关。
注:其实度量也属于一个维度,即度量维。所有的度量构成了度量维。
成员 表示属于某个维度中维表的实际数据值。每个属性都具有与其关联的数据值或成员的集合。 在我们的示例中,“发货区域”维度的成员包括东北、华北、华东、华南、华中、西南,“年”维度的成员包括2020,2021。
计算成员 表示属于某个维度中维表的不存在的数据值,通过表达式计算其对应的度量值。可以在用户查询或 MDX 计算脚本中定义计算成员,并将其存储在服务器上。 一个计算成员对应于定义该成员的维度中的多个维度表行。在我们的示例中,“发货区域”和“时间”维度的计算成员都是是合计,但这是两个不同维度的计算成员。
计算度量 不存在于事实表的数据列, 通过表达式计算其对应数值。在上图中,销售目标是计算度量,通过表达式:销售额 * 1.3获得。
单元 是指度量值维度的成员与模型中各个维度的成员相交处所在的空间。在上图中,[发货区域].[(All)].[东北], [订单日期] .[(All)].[2020],[measure].[销售目标]的对应的单元值为83128
元组 元组由数据模型中每个维度的一个成员组成,所以元组可以唯一标识多维数据集中的每个单元。在 MDX 查询或表达式中定义元组时,不必显式包含每个属性层次结构中的属性成员。 如果属性层次结构中的成员未显式包含在查询或表达式中,则该属性层次结构的默认成员为隐式包含在元组中的属性成员。 除非在多维数据集中进行显式定义,否则每个属性层次结构的默认成员均为“(全部)”成员(如果存在“(全部)”成员)。 如果属性层次结构中不存在“(全部)”成员,则默认成员为属性层次结构中的顶级成员。 除非显式定义了默认度量值,否则默认度量值为多维数据集中指定的第一个度量值。也就是说上图中的元组([发货区域].[(All)].[东北], [订单日期] .[(All)].[2020]) 等价于([发货区域].[(All)].[东北], [订单日期] .[(All)].[2020], [产品类别].[(All)], [产品名称].[(All)] , [公司类型].[(All)], ….[(All)],….[(All)],….)
集合 元组或同一维度的成员的有序集合称为集合(Set)。在 MDX 查询中,轴维度和切片器维度由这种元组集合组成。以下示例是对上图中中的一个元组集合的描述。
{([发货区域].[(All)].[东北], [订单日期] .[(All)].[2020]), ([发货区域].[(All)].[东北], [订单日期] .[(All)].[2021]), ([发货区域].[(All)].[华北], [订单日期] .[(All)].[2020]) , ([发货区域].[(All)].[华北], [订单日期] .[(All)].[2021]),…………}
成员集合的描述:{[发货区域].[(All)].[东北], [发货区域].[(All)].[华北], [发货区域].[(All)].[华东]……}
成员集合的描述:[订单日期] .[(All)].[2020], [订单日期] .[(All)].[2021]}
其他模型相关概念
本部分是一系列概念和术语,这些概念和术语在表格中并没有直接体现,但你仍需要了解,这个概念可能在MDX会被使用。
级别 存在同一维度上维表中不同列。在上图中,“发货区域”这个维度的级别有“(All)”, “发货区域”, “省份”, “发货城市”。其中“(All)”这级别为所以维度的都存在的级别,该级别存在唯一的一个“[发货区域].[(All)]”,代表发货区域所有值的集合。级别“发货区域”, “省份”, “发货城市”分别对应维表“订单表”的“发货区域”, “省份”, “发货城市”的列,级别“发货区域”下的成员“[发货区域].[(All)].[华北]”也就对应“发货区域”列的值“华北”。级别主要用于仪表盘上的下钻操作
父子成员 同一维度上不同级别成员之间的的关系。在下图中,“[发货区域].[(All)]”作为“[发货区域].[(All)].[华北]”的父成员,“[发货区域].[(All)].[华北].[吉林省]” 作为“[发货区域].[(All)].[华北]”的子成员
成员唯一真名 在数据模型中可以唯一标识成员的标记。通常格式为“[维度名].[第一级别的祖先成员名].[第二级别的父成员名].[当前成员名]”,例如:“[发货区域].[(All)].[华北].[吉林省]”中,“发货区域”为维度名,“(All)”为第一级别“(All)”下对应的祖先成员名,“华北”为第二级别“省份”下对应的祖先成员名,“吉林省”为自身的成员名,
成员别名 数据模型的成员在前端展示时显示的内容,成员唯一真名虽然可以代表成员,但是其名称太多,用户不好理解,所以在前端展示时使用成员别名,成员别名可能存在同名的情况。
3 MDX 语法简介
以下语法显示了一个包括 SELECT、FROM 和 WHERE 子句的基本 SELECT 语句用法:
[ WITH <SELECT WITH clause> [ , <SELECT WITH clause> ... ] ] SELECT [<axis_specification> [, <axis_specification>...]] FROM [<cube_specification>] [WHERE [<slicer_specification>]] |
MDX SELECT 语句支持可选的语法(如 WITH 关键字),支持使用 MDX 函数来创建计算成员以便确定是否包含在轴或切片器轴中,并支持在查询中返回特定单元属性的值。
比较 MDX SELECT 语句的语法与 SQL 语法,MDX SELECT 语句所用的语法格式与 SQL 语法相似。 但也有几个基本差异:
- MDX 语法通过大括号({和 } characters (周围元组或成员来区分集。) 有关成员、元组和集语法的详细信息,。
- MDX 查询在 SELECT 语句中可有 0、1、2查询轴。 每个轴具有完全相同的行为方式,这一点与 SQL 不同,后者的查询行为中,行和列之间存在显着的差异。
- 像SQL 查询一样,FROM 子句可为 MDX 查询指定数据源。 但是,MDX FROM 子句被限定为单个数据模型。
- WHERE 子句描述了 MDX 查询中的切片器轴。它的作用就像一个无形的东西(查询中的额外轴),会对结果集的单元中显示的值进行切片;而 SQL WHERE 子句则不同,它不会直接影响查询的行轴上显示的内容。 可通过其他 MDX 功能(如 FILTER 函数)来获得 SQL WHERE 子句的功能。
SELECT 语句示例
以下示例显示了使用 SELECT 语句的基本 MDX 查询。
WITH member [发货区域].[(All)].[SMARTBI合计] as aggregate ([发货区域].[发货区域].members),SOLVE_ORDER = 50 SELECT ({ [日期].[年].members * [Measures].[销售额], [日期].[(all)].[SMARTBI合计] * [Measures].[销售额] } ON COLUMNS, {[发货区域].[发货区域].members, [发货区域].[(All)].[SMARTBI合计]} ON ROWS FROM [cube] WHERE [CategoryName].[(All)].[点心] |
此查询返回包含”发货区域”的所有年份的点心的销售额的结果。
在此示例中,此查询定义了以下结果集信息:
- SELECT 子句将查询列轴设置为 Measures 维度的[Measures].[销售额]成员,以及“日期” 维度的 “年份”级别的所有成员,查询行轴设置为“发货区域” 维度的 “发货区域”级别的所有成员。
- WHERE 子句将切片器轴定义为 “产品类别”维度的 [CategoryName].[(All)].[点心] 成员。
- With 部分定义了“发货区域” 维度的计算成员合计,公式为“发货区域” 维度的 “发货区域”级别的所有成员的集合结果。
4 MDX 语法元素
4.1 标识符
标识符是对象的名称。 每个对象都可以且必须具有标识符。 这些对象包括数据模型、维度、层次结构、级别、成员等等。 可以使用对象的标识符在多维表达式 (MDX) 语句中引用对象。
根据命名对象的方式,对象标识符可以是常规标识符,也可以是分隔标识符。
使用常规标识符
常规标识符是符合成为常规标识符的下列格式规则的对象名称。 常规标识符可以和分隔符一起使用,也可以不和分隔符一起使用。
常规标识符的格式规则
- 第一个字符必须是下列字符之一:
Unicode Standard 2.0 定义的字母。 除了其他语言的字母字符外,Unicode 定义的字母还包括从 a 到 z 以及从 A 到 Z 的拉丁字符。
下划线 (_) 。
- 后续字符可以是:
Unicode Standard 2.0 中定义的字母。
基本拉丁字符或其他国家/地区字符中的十进制数字。
下划线 (_) 。
- 标识符一定不能是MDX 保留关键字。 MDX 中的保留关键字区分大小写。 有关详细信息,请参阅 保留关键字 (MDX 语法) 。
- 不允许嵌入空格或特殊字符。
常规标识符的示例
在以下 MDX 语句中,标识符 Measures、CategoryName都符合常规标识符的格式规则。 这些常规标识符不需要使用分隔符。
SELECT Measures.MEMBERS ON COLUMNS,
CategoryName.CategoryName.CHILDREN ON ROWS
FROM [cube]
虽然没有要求,但您也可以将分隔符和常规标识符一起使用。 在以下 MDX 语句中,通过使用方括号正确地分隔了常规标识符 Measures、Product 和 Style。
SELECT [Measures].MEMBERS ON COLUMNS,
[CategoryName].[CategoryName].CHILDREN ON ROWS
FROM [cube]
使用分隔标识符
下列情况下需要使用分隔标识符:
- 当对象的名称或名称中的一部分使用保留关键字时。
建议不要将保留关键字用作对象名称。
- 当对象的名称使用未被列为限定标识符的字符时。
MDX许带分隔符的标识符使用当前代码页中的任何字符。 但是,不加选择地在对象名称中使用特殊字符会使 MDX 语句和脚本难以读取和维护。
分隔标识符的格式规则
分隔标识符的主体可以包含当前代码页中的字符(包括分隔符本身)的任意组合。 如果分隔标识符的主体包含分隔符,则需进行特殊处理:
- 如果标识符的主体只包含左方括号([),则无需进行额外处理。
- 如果标识符的主体包含一个右方括号(]),则必须指定两个右方括号 (]])。
分隔标识符的示例
在以下假设 MDX 语句中,Sales Volume、Sales Cube 和 select 都是分隔标识符:
SELECT Measures.[Sales Volume]
FROM [Sales Cube]
WHERE Product.[select]
在下面的这个示例中,对象的名称是 Total Profit [Domestic]。 若要引用此对象,必须使用以下分隔标识符:
[Total Profit [Domestic]]]
请注意,不必更改 Domestic 前面的左方括号来创建分隔标识符。 但是,必须将 Domestic 后面的右方括号替换为两个右方括号。
4.2 表达式
4.2.1 表达式
表达式是标识符、值和运算符的组合,可以计算这些标识符、值和运算符来获取结果。 访问或更改数据时,可以在多个不同位置使用数据。 例如,可以将表达式用作查询要检索的数据的一部分,或用作查找满足一组条件的数据的搜索条件。
简单表达式和复杂表达式
在 MDX 中,表达式可以是简单的,也可以是复杂的:
简单表达式可以是下列几种表达式之一:
- 常数
在 MDX 中,常量是表示单个特定值的符号。 字符串、数字和日期值可以呈现为常量。 与数值常量不同,字符串和日期常量必须用单引号 (') 字符分隔开。
- 标量函数
在 MDX 中,标量函数返回计算上下文内的单个值。 此区别对于理解 MDX 如何解析标量函数很重要,因为不是对单个数据元素计算大多数 MDX 表达式、语句和脚本,而是重复地对一组数据元素(如单元或成员)进行计算。 但在计算标量函数时,函数通常查看单个数据元素。
- 对象标识符
由于多维数据的本质,因此 MDX 是面向对象的。 在 MDX 中,对象标识符被视为简单表达式。
可以从用运算符联接的这些实体的组合生成复杂表达式。
表达式示例
以下查询说明其定义是简单表达式的计算度量值的示例:
WITH
MEMBER MEASURES.X1 AS 1
MEMBER MEASURES.X2 AS [日期].[年份].CURRENTMEMBER.NAME
MEMBER MEASURES.X3 AS [Measures].[销售额]
SELECT { MEASURES.X1, MEASURES.X2, MEASURES.X3 } ON COLUMNS,
[日期].[年份].MEMBERS ON ROWS
FROM [cube]
表达式还可以是计算,例如 [Measures].[销售额] * 1.5。 下面的示例说明如何在 MDX SELECT 语句使用计算来定义成员:
WITH MEMBER [Measures].[销售额_ Special] AS [Measures].[销售额] * 1.5 SELECT [Measures].[销售额_Special] on COLUMNS, N[日期].[年份].MEMBERS ON Rows FROM [cube] |
4.2.2维度表达式
将参数传递给多维表达式 (MDX) 中的函数时,通常使用维度表达式和层次结构表达式从层次结构中返回成员、集或元组。
因为维度表达式是对象标识符,所以它们只能是简单表达式。
维度表达式
维度表达式包含维度标识符或维度函数。
以下示例说明计算成员,它使用表达式 [Measures] 以及 .Members 和 Count() 函数来返回 Measures 维度上成员的数目。
WITH MEMBER [Measures].[MeasureCount] AS COUNT([Measures].MEMBERS) SELECT [Measures].[MeasureCount] ON COLUMNS FROM [cube] |
维度标识符在用于描述 MDX 语句的 BNF 表示法中显示为 Dimension_Name 。
4.2.3成员表达式
成员表达式包含成员标识符、成员函数或可转换为成员的表达式。
成员标识符的最简单形式由成员的成员唯一真名组成。 例如:
SELECT [Measures].[销售额] ON COLUMNS
FROM [cube]
存在返回成员的许多 MDX 函数。
4.2.4元组表达式
元组由多维数据集中包含的每个维度的一个成员组成。 因此,一个元组唯一标识多维数据集内的一个单元。
元组标识符的完整表达式由一个或多个用括号括起的显式指定的成员组成:
(Member_expression [ ,Member_expression ... ] )
元组可以是完全限定的,可以包含多个隐式成员,也可以只包含一个成员。
元组和隐式成员
显式指定数据模型内包含的每个维度的一个成员的元组称为“完全限定元组”。 但是,元组没有必要是完全限定的。
元组内没有显式引用的任何维度都被隐式引用。 隐式引用的维度的成员取决于维度的结构和在维度内定义的属性关系。以下规则适用:
- 如果隐式引用的维度有默认成员,则将该默认成员添加到元组中。
- 如果隐式引用的维度没有默认成员,则使用(默认维度的所有 ) 成员。
- 如果隐式引用的维度没有默认成员,则使用该维度最上层的第一个成员。
4.2.5集表达式
集由零个或多个元组的有序列表组成。 不包含任何元组的集称为“空集”。
一个集的完整表达式由零个或多个显式指定的元组构成,各元组放在大括号中:
{ [ { Tuple_expression | Member_expression } [ , { Tuple_expression | Member_expression } ] ... ] }
集表达式中指定的成员表达式将被转换为由一个成员构成的元组表达式。
示例
以下示例说明在查询的列和行轴上使用的两个集表达式:
SELECT
{[Measures].[销售额], [Measures].[销售量]} ON COLUMNS,
{([CategoryName].[(All)].[点心], [日期].[年份].[2020]),
([CategoryName].[(All)].[海鲜], [日期].[年份].[2021]),
([CategoryName].[(All)].[调味品], [日期].[年份].[2020])}
ON ROWS
FROM [cube]
在列轴上,集{[Measures].[销售额], [Measures].[销售量]}
由 Measures 维度的两个成员组成。
在行轴上,集
{([CategoryName].[(All)].[点心], [日期].[年份].[2020]),
([CategoryName].[(All)].[海鲜], [日期].[年份].[2021]),
([CategoryName].[(All)].[调味品], [日期].[年份].[2020])}
由三个元组组成,每个元组包含对“产品类别”维度和 “日期” 维度上成员的两个显式引用。
4.2.6常量表达式
在多维表达式 (MDX) 中,标量表达式是 MDX 语法的一个元素;在计算时,它在计算上下文中返回单个值。
标量表达式包括 MDX 中的字符串表达式、数值表达式和日期表达式。
由于计算成员必须返回标量值,因此标量表达式通常用于计算成员定义。 以下查询说明 Measures 维度上使用不同类型标量表达式的计算成员的示例:
WITH
MEMBER MEASURES.NumericValue AS 10
MEMBER MEASURES.NumericExpression AS 10 + 10
MEMBER MEASURES.NumericExpressionBasedOnMeasure AS [Measures].[Internet Sales Amount] + 10
MEMBER MEASURES.StringValue AS "10"
MEMBER MEASURES.ConcatenatedString AS "10" + "10"
MEMBER MEASURES.StringFunction AS MEASURES.CURRENTMEMBER.NAME
MEMBER MEASURES.TodaysDate AS NOW()
SELECT
{MEASURES.NumericValue,MEASURES.NumericExpression,MEASURES.NumericExpressionBasedOnMeasure,MEASURES.StringValue, MEASURES.ConcatenatedString, MEASURES.StringFunction, MEASURES.TodaysDate} ON COLUMNS
FROM [cube]
4.2.7空值
空值表明特定成员、元组或单元是空的。 空单元值指明在基础事实表中找不到指定单元的数据,或者指定单元的元组代表不适用于数据模型的成员组合。
备注:
虽然空值有别于零值,但是通常大多数情况下都将空值作为零处理。
以下信息适用于空值:
- 当且仅当函数中指定的元组标识的单元格为空时,IsEmpty 函数才返回 TRUE 。 否则,函数返回 FALSE。
- 当空单元值是数字运算符(+、-、*、/)中任一运算符的一个操作数时,如果另一个操作数是非空值,空单元值将被作为零处理。 如果两个操作数都为空,数字运算符将返回空单元值。
- 当空单元值是字符串串联运算符(+) 的一个操作数时,如果另一个操作数是非空值,空单元值将被作为空字符串处理。 如果两个操作数都为空,字符串串联运算符将返回空单元值。
- 当空单元格值是任意一个比较运算符的操作数时,(=。 <>、 >=、 <=、 >、 <) ,空单元格值被视为零或空字符串,具体取决于另一个操作数的数据类型是数值还是字符串。 如果两个操作数都为空,则两个操作数均作为零处理。
- 当对数字值进行排序时,空单元值排在与零相同的位置。在空单元值和零之间,空单元值排在零之前。
- 当对字符串值进行排序时,空单元值排在与空字符串相同的位置。在空单元值和空字符串之间,空单元值排在空字符串之前。
4.3运算符
4.3.1运算符
在多维表达式 (MDX) 中,可以使用运算符执行下列操作:
- 永久或临时更改数据。
- 搜索满足指定条件的值或对象。
- 在值或表达式之间进行判断。
- 在开始或提交事务之前,或在执行特定语句之前测试特定条件。
MDX 支持下表中列出的运算符:
若要执行这种运算 | 使用 |
为变量赋值,或将结果集列与别名相关联。 | 赋值运算符 |
加法、减法、乘法、除法。 | 算术运算符 |
测试某个条件(如 AND、OR、NOT 和 XOR)的真实性。 | 位运算符 |
将一个值与另一个值或表达式进行比较。 | 比较运算符 |
永久或临时将两个字符串合并成一个字符串。 | 串联运算符 |
永久或临时将两个集表达式合并成一个集。 | set 运算符 |
对一个操作数执行操作。 | 一元运算符 |
同时使用多个运算符时,MDX 计算运算符的顺序非常重要。 同样,运算符的用户可能需要在计算运算符之前将一个数据类型转换为另一个数据类型。
计算复杂表达式
可以通过使用运算符合并几个较小的表达式来生成一个表达式。 在这些复杂表达式中,MDX 根据使用的运算符优先级定义按顺序计算运算符。 MDX 先计算具有较高优先级的运算符,后计算具有较低优先级的运算符。
了解运算符优先级
以下列表显示了运算符优先级,按从最高到最低的顺序排列。 位于同一行中的运算符具有相同的优先级,按从左到右的顺序进行计算,除非使用括号进行强制:
- IS
- ^
- /, *
- +, -
- <>, >=, =, <=, >, <
- NOT
- AND
- XOR
- OR
4.3.2算术运算符
可以在多维表达式 (MDX) 中使用算术运算符执行算术运算,包括加法、减法、乘法以及除法。
MDX 支持下表中列出的算术运算符。
运算符 说明
+(加) 两个数相加。
/(除) 将一个数除以另一个数。
*(乘) 使两个数字相乘。
-(减) 两个数相减。
^(幂) 以一个数为底,另一个数为幂求值。
优先顺序
下列规则确定了 MDX 表达式中各算术运算符的优先顺序:
如果表达式中有多个算术运算符,则 MDX 先计算乘除,后计算加减。
如果表达式中的所有算术运算符都具有相同的优先顺序,则执行顺序为从左到右。
括号中的表达式优先于所有其他运算。
4.3.3位运算符
逻辑运算符计算值并返回布尔值。 在多维表达式 (MDX) 中,逻辑运算符不执行按位运算。
MDX 支持下表中列出的逻辑运算符。
操作符 说明
AND 对两个数值表达式执行逻辑与运算。
IS 对两个对象表达式执行逻辑比较。
NOT 对数值表达式执行逻辑非运算。
OR 对数值表达式执行逻辑或运算。
XOR 对两个数值表达式执行逻辑异运算。
4.3.4比较运算符
可以对标量数据使用比较运算符。 可以在任何多维表达式 (MDX) 表达式中使用比较运算符。
若要检查某个条件,还可以在 MDX 语句和函数中使用比较运算符,例如 MDX IIf 函数。
比较运算符的计算结果为布尔数据类型,并根据所测试条件的输出结果返回 TRUE 或 FALSE。
MDX 支持下表中列出的比较运算符。
运算符 描述
= (等于) 对于非空的参数,如果左边的参数等于右边的参数,则返回 TRUE;否则返回 FALSE。如果任一参数的计算结果等于空值或两个参数的计算结果都等于空值,此运算符将返回空值,除非进行了 0=null 比较,在这种情况下,布尔值中将包含 TRUE。
<>(不等于) 对于非空的参数,如果左边的参数不等于右边的参数,则返回 TRUE;否则返回 FALSE。如果其中一个参数的计算结果为空值或这两个参数的计算结果均为空值,则该运算符返回空值。
>(大于) 对于非空的参数,如果左边的参数值大于右边的参数,则返回 TRUE;否则返回 FALSE。如果其中一个参数的计算结果为空值或这两个参数的计算结果均为空值,则该运算符返回空值。
>=(大于或等于) 对于非空的参数,如果左边的参数值大于或等于右边的参数,则返回 TRUE;否则返回 FALSE。如果其中一个参数的计算结果为空值或这两个参数的计算结果均为空值,则该运算符返回空值。
<(小于) 对于非 null 参数,如果左参数的值小于右参数,则返回 TRUE;否则为 FALSE。如果其中一个参数的计算结果为空值或这两个参数的计算结果均为空值,则该运算符返回空值。
<=(小于或等于) 对于非空的参数,如果左边的参数值小于或等于右边的参数,则返回 TRUE;否则返回 FALSE。如果其中一个参数的计算结果为空值或这两个参数的计算结果均为空值,则该运算符返回空值。
4.3.5串联运算符
串联运算符为(||)。 可以将两个或更多个字符串合并或串联成一个字符串, 还可以串联二进制字符串。
下列代码是串联运算符的一个示例,在此示例中,用串联运算符将产品名称与产品的唯一名称连接起来:
WITH MEMBER Measures.ProductName AS CategoryName.CurrentMember.Name || " (" || CategoryName.CurrentMember.UniqueName || ")" SELECT {Measures.ProductName} ON COLUMNS, CategoryName.CategoryName.Members ON ROWS FROM [cube] |
4.3.6集运算符
在多维表达式 (MDX) 中,集运算符对成员或集进行运算并返回一个集。 通常用集运算符替换 MDX 表达式中的多个集函数。
MDX 支持下表中列出的集运算符。
运算符 说明
-(排除) 返回两个集之间的不同项,并删除重复的成员。此运算符在功能上等效于 Except 函数。
*(叉积) 返回两个集的叉积。此运算符在功能上等效于 Crossjoin 函数。
:(范围) 返回自然排序的集,并将两个指定的成员作为终结点,这两个指定成员之间的所有成员都作为集的成员包括在其中。
+ (Union) 返回两个集的并集,不包括重复的成员。此运算符在功能上等效于 Union (MDX) 函数。
4.3.7一元运算符
在多维表达式 (MDX) 中,一元运算符对单个操作数执行操作,如返回数值表达式的负值或正值。
MDX 支持下表中列出的一维运算符。
运算符 说明
-(负) 返回数值表达式的负值。
+(正) 返回数值表达式的正值。
下面的示例显示了如何使用一维运算符返回度量值的负值:
WITH MEMBER Measures.ProductName AS -Measures._销售额_1624531356707 SELECT {Measures.ProductName} ON COLUMNS, CategoryName.CategoryName.Members ON ROWS FROM [cube] |
4.4函数
多维表达式 (MDX) 中有几类用于执行特定操作的内部函数。 下表列出了 MDX 中可用的函数类别。
时间函数 计算同环比等时间计算的函数
fixed类函数
日期函数 计算日期的函数
聚合函数 计算合计,平均值等集合计算的函数
逻辑函数 对对象和表达式执行逻辑操作和比较。
字符串函数 从其他对象或从服务器返回字符串值。
集合函数 从其他对象或从字符串表达式返回对集的引用。
维度函数/级别函数 从层次结构、级别或成员返回对维度的引用。/从成员、维度、层次结构或字符串表达式返回对级别的引用。
成员函数 从其他对象或从字符串表达式返回对成员的引用。
数值函数 对对象和表达式执行数学函数和统计函数。
元组函数 从集或从字符串表达式返回对元组的引用。
函数格式说明:
函数名(参数1类型,参数2类型,…,…)
示例1:
PeriodCumulative(<Level>, <Numeric Expression>, <Member>)
PeriodCumulative 代表函数名
<Level> 代表 参数1为级别表达式
<Numeric Expression> 代表 参数2为常量的数值表达式
<Member> 代表 参数3为成员表达式
示例2:
Intersect(<Set1>, <Set2>[, ALL])
Intersect代表函数名
< Set1> 代表 参数1为集表达式
< Set2> 代表 参数2为集表达式
[] 代表 参数3为可选参数
ALL 代表固定的保留字
参数类型说明:
<Hierarchy> 层次结构表达式(注:在模型等同维度表达式)
<Set> 集表达式
<Numeric Expression> 常量数值表达式
<String Expression> 常量字符串表达式
<Level> 级别表达式
<Member> 成员表达式
<Logical Expression> 常量布尔表达式
<tuple> 元组表达式
4.5注释
注释是程序代码中不执行的文本字符串。 (注释又称为“备注”。) 可以使用注释说明代码,或者暂时禁用正在诊断的部分多维表达式 (MDX) 语句和脚本。 通过使用注释说明代码,可使程序代码在日后更易于维护。 通常使用注释记录程序名称、作者姓名和主要代码更改的日期。 也可以使用注释说明复杂的计算或解释编程方法。
MDX 中的注释遵循下列指导原则:
- 注释中可以使用所有字母数字字符或符号。忽略批注中的所有字符。
- 语句或脚本中的注释没有最大长度限制。一条注释可由一行或多行组成。
MDX 支持三种类型的注释字符:
- //(双正斜杠)
这些注释字符可与要运行的代码在同一行上,也可单独成一行。 从双正斜杠开始到行尾均为注释部分。 对于多行注释,每个注释行的开始都必须出现双正斜杠。
- --(双连字符)
这些注释字符可与要运行的代码在同一行上,也可单独成一行。 从双连字符开始到行尾均为注释部分。 对于多行注释,每个注释行的开始都必须出现双连字符。
- /* ... */ (正斜杠星号字符对)
这种注释字符可在要运行的代码行中使用,可以单独成行,也可以位于可执行代码中。 开始注释字符对 (/*) 与结束注释字符对 (*/) 之间的所有内容均为注释。 对于多行注释,必须使用开始注释字符对 (/*) 开始注释,使用结束注释字符对 (*/) 结束注释。 注释的任何行中均不能出现其他注释字符。
以下查询说明上述三种注释的示例:
//An example of a comment using the double-forward slash --An example of a comment using the double-hypen /*An example of a multi-line comment*/ WITH MEMBER Measures.ProductName AS -Measures._销售额_1624531356707 SELECT {Measures.ProductName} ON COLUMNS, CategoryName.CategoryName.Members ON ROWS FROM [cube] --[] |
4.5 保留字
下表包含多维表达式 (MDX) 使用的保留字。 在 MDX 中,不应在任何标识符(例如多维数据集名称或用户定义的函数名称)中使用这些保留字。
AGGREGATE,ALL,ALLMEMBERS,ANCESTOR,ANCESTORS,AND,AS,ASC,ASCENDANTS,AVERAGE,AXIS,BASC,BDESC,BOTTOMCOUNT,BOTTOMPERCENT,BOTTOMSUM,CHILDREN,CLEAR,COLUMN,COLUMNS,CORRELATION,COUNT,COUSIN,CROSSJOIN,CUBE,CURRENT,CURRENTCUBE,CURRENTMEMBER,DEFAULT_MEMBER,DEFAULTMEMBER,DESC,DESCENDANTS,DIMENSION,DIMENSIONS,DISTINCT,DISTINCTCOUNT,EMPTY,ERROR,EXCEPT,FALSE,FILTER,FIRSTCHILD,FIRSTSIBLING,FROM,GENERATE,HEAD,HIERARCHIZE,HIERARCHY,IIF,INCLUDEEMPTY,INDEX,IS,ISANCESTOR,ISEMPTY,ISGENERATION,ISLEAF,ISSIBLING,ITEM,LAG,LASTCHILD,LASTPERIODS,LASTSIBLING,LEAD,LEVEL,LEVELS,MAX,MEASURE,MEMBER,MEMBERS,MEMBERTOSTR,MIN,MTD,NAMETOSET,NEXTMEMBER,NONEMPTYCROSSJOIN,Null,ON,OR,PARENT,PERIODSTODATE,POST,PREVMEMBER,PROPERTY,QTD,RANK,RECURSIVE,ROWS,SELECT,SET,SETTOSTR,SORT,STORAGE,STRTOMEMBER,STRTOSET,STRTOTUPLE,STRTOVAL,STRTOVALUE,SUBSET,SUM,TAIL,TOPCOUNT,TOPPERCENT,TOPSUM,TOTALS,TRUE,UNION,UNIQUE,UNIQUENAME,WHERE,WITH,WTD,XOR,YTD