第1章 什么是DAX?
1.1 理解数据模型
1.2 DAX FOR EXCEL用户
1.3 DAX for SQL开发人员
1.4 DAX for MDX开发人员
1.5 DAX FOR POWER BI 用户
DAX for MDX开发人员
许多商业智能专业人员开始学习DAX,因为它是Tabular的新语言。过去,他们使用MDX语言来构建和查询Analysis Services多维模型。如果您是其中的一员,请准备学习一种全新的语言:DAX和MDX并没有太多共同之处。更糟糕的是,DAX中的某些概念会让您想起MDX中类似的现有概念,尽管它们有所不同。
根据我们的经验,发现在学习MDX之后学习DAX是最具挑战性的选择。要学习DAX,您需要从MDX上解放思想。尝试忘记关于多维空间的所有知识,并准备以清晰的头脑学习这种新语言。
多维与表格
MDX在模型定义的多维空间中工作。多维空间的形状基于模型中定义的维和层次结构的体系结构,而这又定义了多维空间的坐标集。不同维数的成员集的相交定义了多维空间中的点。您可能已经花了一些时间意识到任何属性层次结构的[All]成员确实是多维空间中的一个点。
DAX以更简单的方式工作。多维空间中没有维,没有成员,也没有点。换句话说,根本没有多维空间。我们可以在模型中定义层次结构,但它们与MDX中的层次结构不同。DAX空间建立在表,列和关系之上。表格模型中的每个表既不是度量值组也不是维:它只是一个表,要计算值,请对其进行扫描,筛选或对其中的值求和。一切都基于表和关系这两个简单的概念。
您很快就会发现,从建模的角度来看, Tabular提供的选项少于多维。在这种情况下,拥有较少的选项并不意味着功能不那么强大,因为您可以使用DAX作为编程语言来丰富模型。Tabular真正的建模能力是DAX的惊人速度。实际上,您可能会尝试避免在模型中过度使用MDX,因为优化MDX速度通常是一个挑战。另一方面,DAX非常快。因此,大多数计算复杂性不在模型中,而在DAX公式中。
DAX作为一种编程和查询语言
DAX和MDX都是编程语言和查询语言。在MDX中,通过MDX脚本的存在可以清楚地看出差异。您可以在MDX脚本中使用MDX以及几个只能在脚本中使用的特殊语句,例如SCOPE语句。在编写SELECT检索数据的语句时,在查询中使用MDX。在DAX中,这有些不同。您可以使用DAX作为编程语言来定义计算列,计算表和度量值。计算列和计算表的概念是DAX的新增功能,在MDX中不存在。度量值与MDX中的计算成员相似。您还可以将DAX用作查询语言,例如,使用Reporting Services从表格模型中检索数据。但是,DAX函数没有特定的作用,可以在查询和计算表达式中使用。此外,您还可以使用MDX查询表格模型。因此,MDX的查询部分适用于表格模型,而DAX是表格模型编程的唯一选择。
层次结构
使用MDX,您可以依靠层次结构来执行大多数计算。如果要计算上一年的销售额,则必须在Year层次结构中检索CurrentMember的PrevMember,并使用它覆盖MDX过滤器。例如,您可以使用这种方式编写公式,以在MDX中定义上一年的计算:
CREATE MEMBER CURRENTCUBE.[Measures].
[SamePeriodPreviousYearSales] AS
(
[Measures].[Sales Amount],
ParallelPeriod (
[Date].[Calendar].[Calendar Year],
1,
[Date].[Calendar].CurrentMember
)
);
该度量值使用ParallelPeriod函数,该函数返回Calendar层次结构上CurrentMember的表亲。因此,它基于模型中定义的层次结构。我们将使用筛选上下文和标准时间智能函数在DAX中编写相同的计算:
SamePeriodPreviousYearSales :=
CALCULATE (
SUM ( Sales[Sales Amount] ),
SAMEPERIODLASTYEAR ( 'Date'[Date] )
)
我们可以使用FILTER和其他DAX函数以许多其他方式编写相同的计算,但是想法仍然相同:我们不使用层次结构,而是过滤表。这种差异是巨大的,在您习惯DAX之前,您可能会错过层次结构计算。
另一个重要的区别是,在MDX中,您引用了[Measures].[Sales Amount],并且模型中已经定义了您需要使用的聚合函数。在DAX中,没有预定义的聚合。实际上,您可能已经注意到,要计算的表达式是SUM(Sales [Sales Amount])。预定义的聚合不再存在于模型中。每当需要使用它时,我们都需要对其进行定义。我们总是可以创建一个计算销售额之和的量度值,但这将超出本节的范围,稍后将在书中进行解释。
DAX和MDX之间的另一个重要区别是,MDX大量使用SCOPE语句来实现业务逻辑(再次使用层次结构),而DAX需要完全不同的方法。实际上,该语言完全没有层次结构处理。
例如,如果我们想清除一项Year级别的度量值,在MDX中,我们将编写以下语句:
SCOPE ( [Measures].
[SamePeriodPreviousYearSales], [Date].[Month].
[All] )
THIS = NULL;
END SCOPE;
DAX没有类似SCOPE语句的内容。为了获得相同的结果,我们需要检查筛选上下文中是否存在筛选,并且场景要复杂得多:
SamePeriodPreviousYearSales :=
IF (
ISINSCOPE ( 'Date'[Month] ),
CALCULATE (
SUM ( Sales[Sales Amount] ),
SAMEPERIODLASTYEAR ( 'Date'[Date] )
),
BLANK ()
)
直观地,仅当用户在月份级别或更低级别浏览日历层次结构时,此公式才返回一个值。否则,它返回BLANK。稍后,您将详细了解此公式的计算结果。它比等效的MDX代码更容易出错。老实说,层次处理是DAX真正缺少的功能之一。
叶级计算
最后,在使用MDX时,您可能习惯于避免进行叶级计算。事实证明,在MDX中执行叶级计算是如此之慢,以至于您总是喜欢预先计算值并利用聚合来返回结果。在DAX中,叶级计算的工作速度非常快,并且聚合有不同的用途,仅对大型数据集有用。这需要在构建数据模型时改变观念。在大多数情况下,完全适合SSAS多维数据模型不适用于表格,反之亦然。
网友评论