了解传递顺序和求解顺序 (MDX)

当数据集立方体作为 MDX 脚本的结果进行计算时,它可能会经历许多计算阶段,具体取决于各种计算相关功能的使用。 每个阶段称为一个计算过程。

计算过程可以通过序数位置(称为计算过程序号)来引用。 完全计算多维数据集的所有单元格所需的计算传递计数称为多维数据集的计算传递深度。

事实表和回写数据仅影响阶段 0。 脚本在传递 0 后填充数据;脚本中的每个赋值和计算语句都会创建新的传递。 在 MDX 脚本之外,对绝对通道 0 的引用是指该脚本为多维数据集创建的最后一个通道。

计算成员在所有传递中创建,但表达式在当前传递中应用。 先前的步骤包含计算度量值,但值为空。

求解顺序

求解顺序确定争用表达式时计算的优先级。 在单次遍历中,求解顺序决定了两件事情:

  • Microsoft SQL Server Analysis Services 评估维度、成员、计算成员、自定义汇总和计算单元格的顺序。

  • Analysis Services 计算自定义成员、计算成员、自定义汇总和计算单元格的顺序。

具有最高求解顺序的成员优先。

注释

此优先级的例外是 Aggregate 函数。 具有 Aggregate 函数的计算成员的求解顺序低于任何相交计算度量值。

求解顺序值和优先级

求解顺序值的范围可以是 -8181 到 65535。 在此范围内,某些求解顺序值对应于特定类型的计算,如下表所示。

计算 求解顺序
自定义成员公式 -5119
一元运算符 -5119
视觉汇总计算 -4096
所有其他计算(除非另有说明) 0

强烈建议在设置求解顺序值时仅使用正整数。 如果分配的值低于上表中所示的求解顺序值,计算过程可能会变得不可预知。 例如,计算的成员会接收到一个求解顺序值,该值低于默认的自定义汇总公式值 -5119。 如此低的求解顺序值会导致在自定义汇总公式之前计算计算计算成员,并产生不正确的结果。

创建和更改求解顺序

在多维数据集设计器的 “计算”窗格中,可以通过更改计算的顺序来更改计算成员和计算单元格的求解顺序。

在 MDX 中,可以使用 SOLVE_ORDER 关键字创建或更改计算成员和计算单元格。

求解顺序示例

为了说明求解顺序的潜在复杂性,以下一系列 MDX 查询从两个单独没有解决顺序问题的查询开始。 然后,这两个查询合并为需要求解顺序的查询。

注释

可以针对 Adventure Works 示例多维数据库运行这些 MDX 查询。 可以从 codeplex 站点下载 AdventureWorks 多维模型 SQL Server 2012 示例。

查询 1:收入和支出的差异

对于第一个 MDX 查询,通过构造类似于以下示例的简单 MDX 查询来计算每年的销售额和成本差异:

WITH   
MEMBER  
[Date].[Calendar].[Year Difference] AS ([Date].[Calendar].[Calendar Year].&[2008] - [Date].[Calendar].[Calendar Year].&[2007] )  
SELECT   
{[Measures].[Internet Sales Amount], [Measures].[Internet Total Product Cost] }  
ON COLUMNS ,  
{ [Date].[Calendar].[Calendar Year].&[2007], [Date].[Calendar].[Calendar Year].&[2008], [Date].[Year Difference] }  
ON ROWS  
FROM [Adventure Works]  

在此查询中,只有一个计算成员 Year Difference。 由于只有一个计算成员,因此求解顺序不是问题,只要立方体不使用任何计算成员。

此 MDX 查询生成类似于下表的结果集。

互联网销售金额 Internet 产品总成本
CY 2007 $9,791,060.30 $5,718,327.17
CY 2008 $9,770,899.74 $5,721,205.24
年份差异 (20,160.56美元) $2,878.06

查询支出后的收入百分比

对于第二个查询,使用以下 MDX 查询计算每年支出后的收入百分比:

WITH   
MEMBER  
[Measures].[Profit Margin] AS   
([Measures].[Internet Sales Amount] - [Measures].[Internet Total Product Cost] ) / [Measures].[Internet Sales Amount] ,  
FORMAT_STRING="Percent"  
SELECT   
{[Measures].[Internet Sales Amount], [Measures].[Internet Total Product Cost], [Measures].[Profit Margin] }  
ON COLUMNS ,  
{ [Date].[Calendar].[Calendar Year].&[2007], [Date].[Calendar].[Calendar Year].&[2008] }  
ON ROWS  
FROM [Adventure Works]  

此 MDX 查询(如上一个查询)只有一个计算成员, Profit Margin因此没有任何求解顺序复杂性。

此 MDX 查询生成一个略有不同的结果集,类似于下表。

互联网销售金额 Internet 产品总成本 利润率
CY 2007 $9,791,060.30 $5,718,327.17 41.60%
CY 2008 $9,770,899.74 $5,721,205.24 41.45%

第一个查询和第二个查询的结果集的差异来自计算成员的位置差异。 在第一个查询中,计算成员是 ROWS 轴的一部分,而不是第二个查询中显示的 COLUMNS 轴。 在下一个查询中,位置差异显得尤为重要,因为它将两个计算成员合并到一个单一的 MDX 查询中。

查询 3-合并年度差值和净收入计算

在此最终查询中,将上述两个示例合并到单个 MDX 查询中,由于对列和行的计算,求解顺序变得很重要。 若要确保计算按正确的顺序进行,请使用关键字定义计算的发生 SOLVE_ORDER 顺序。

关键字 SOLVE_ORDER 指定 MDX 查询或 CREATE MEMBER 命令中计算成员的求解顺序。 与关键字一起使用的 SOLVE_ORDER 整数值是相对的,不需要从零开始,也不需要连续。 该值只是告知 MDX 根据从计算具有较高值的成员派生的值来计算成员。 如果未定义计算成员关键字 SOLVE_ORDER ,则计算成员的默认值为零。

例如,如果将前两个示例查询中使用的计算组合在一起,那么两个计算成员Year DifferenceProfit Margin在 MDX 查询示例的结果数据集中的一个单元格处相交。 确定 Analysis Services 如何评估此单元格的唯一方法是按求解顺序。 用于构造此单元格的公式将产生不同的结果,具体取决于两个计算成员的求解顺序。

首先,请尝试合并以下 MDX 查询中前两个查询中使用的计算:

WITH   
MEMBER  
[Date].[Calendar].[Year Difference] AS ([Date].[Calendar].[Calendar Year].&[2008] - [Date].[Calendar].[Calendar Year].&[2007] ) ,  
SOLVE_ORDER = 1  
MEMBER  
[Measures].[Profit Margin] AS   
( [Measures].[Internet Sales Amount] - [Measures].[Internet Total Product Cost] ) / [Measures].[Internet Sales Amount] ,  
FORMAT_STRING="Percent" ,  
SOLVE_ORDER = 2  
SELECT   
{[Measures].[Internet Sales Amount], [Measures].[Internet Total Product Cost], [Measures].[Profit Margin] }  
ON COLUMNS ,  
{ [Date].[Calendar].[Calendar Year].&[2007], [Date].[Calendar].[Calendar Year].&[2008], [Date].[Year Difference] }  
ON ROWS  
FROM [Adventure Works]  

在此组合的 MDX 查询示例中, Profit Margin 具有最高的求解顺序,因此当两个表达式交互时,它优先。 Analysis Services 使用 Profit Margin 公式评估有问题的单元格。 此嵌套计算的结果,如下表所示。

互联网销售金额 Internet 产品总成本 利润率
CY 2007 $9,791,060.30 $5,718,327.17 41.60%
CY 2008 $9,770,899.74 $5,721,205.24 41.45%
年份差异 (20,160.56美元) $2,878.06 114.28%

共享单元格中的结果基于Profit Margin的公式。 也就是说,Analysis Services 在包含Year Difference数据的共享单元格中计算结果,并生成以下公式(结果经过舍入以便更清楚地显示):

((9,770,899.74 - 9,791,060.30) - (5,721,205.24 - 5,718,327.17)) / (9,770,899.74 - 9,791,060.30) = 1.14275744   

(23,038.63) / (20,160.56) = 114.28%  

这显然不正确。 但是,如果切换 MDX 查询中计算成员的求解顺序,Analysis Services 会以不同的方式计算共享单元格中的结果。 以下合并的 MDX 查询将反转计算成员的求解顺序:

WITH   
MEMBER  
[Date].[Calendar].[Year Difference] AS ([Date].[Calendar].[Calendar Year].&[2008] - [Date].[Calendar].[Calendar Year].&[2007] ) ,  
SOLVE_ORDER = 2  
MEMBER  
[Measures].[Profit Margin] AS   
( [Measures].[Internet Sales Amount] - [Measures].[Internet Total Product Cost] ) / [Measures].[Internet Sales Amount] ,  
FORMAT_STRING="Percent" ,  
SOLVE_ORDER = 1  
SELECT   
{[Measures].[Internet Sales Amount], [Measures].[Internet Total Product Cost], [Measures].[Profit Margin] }  
ON COLUMNS ,  
{ [Date].[Calendar].[Calendar Year].&[2007], [Date].[Calendar].[Calendar Year].&[2008], [Date].[Year Difference] }  
ON ROWS  
FROM [Adventure Works]  

由于已切换计算成员的顺序,Analysis Services 使用 Year Difference 公式计算单元格,如下表所示。

互联网销售金额 Internet 产品总成本 利润率
CY 2007 $9,791,060.30 $5,718,327.17 41.60%
CY 2008 $9,770,899.74 $5,721,205.24 41.45%
年份差异 (20,160.56美元) $2,878.06 (0.15%)

由于此查询将 Year Difference 公式与 Profit Margin 数据一起使用,因此该单元格的共享公式类似于以下计算:

(($9,770,899.74 - 5,721,205.24) / $9,770,899.74) - ((9,791,060.30 - 5,718,327.17) / 9,791,060.30) = -0.15   

0.4145 - 0.4160= -0.15  

其他注意事项

解决顺序可能是一个非常复杂的问题,尤其是在涉及大量维度的多维数据集中,包括计算成员、自定义汇总公式或计算单元格的情况下。 当分析服务评估 MDX 查询时,分析服务会考虑当前步骤中所有相关元素的求解顺序值,包括在 MDX 查询中指定的多维数据集的维度。

另请参阅

CalculationCurrentPass (MDX)
CalculationPassValue (MDX)
CREATE MEMBER 语句(MDX)
数据操作(MDX)