第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 EXCEL用户
您可能已经知道DAX有点像的Excel公式语言。毕竟,DAX的根源是Power Pivot for Excel,开发团队试图使这两种语言保持相似。这种相似性使得向这种新语言的过渡更加容易。但是,有一些重要的区别。
单元格与表格
Excel对单元格执行计算。使用其坐标引用单元格。因此,我们可以编写如下公式:
= (A1 * 1.25) - B2
在DAX中,不存在单元格及其坐标的概念。DAX适用于表和列,而不适用于单元格。因此,DAX表达式引用表和列,这意味着编写代码的方式有所不同。
表和列在Excel中的不是新概念。实际上,如果通过使用" 格式为表格" 功能将Excel范围定义为表格,则可以在Excel中编写引用表格和列的公式。在图1一5中,SalesAmount列计算表达式引用同一个表中的列,而不是引用工作簿中的单元格。
图1-5 Excel可以引用表中的列名使用Excel,我们使用[@ColumnName]格式引用表中的列。ColumnName是要使用的列的名称,@符号表示"获取当前行的值"。尽管语法不直观,但是通常我们不编写这些表达式。它们在我们单击单元格时出现,Excel会为我们插入正确的代码。
您可能会认为Excel具有两种不同的执行计算方式。我们可以使用标准单元格引用,在这种情况下,F4的公式为E4 * D4,或者我们可以在表中使用列引用。使用列引用具有以下优点:我们可以在列的所有单元格中使用相同的表达式,并且Excel计算公式将为每一行返回不同的值。
与Excel不同,DAX仅适用于表。所有公式都必须引用表中的列。例如,在DAX中,我们以这种方式编写先前的乘法:
Sales[SalesAmount] = Sales[ProductPrice] *
Sales[ProductQuantity]
如您所见,每列都以其表名作为前缀。在Excel中,我们不提供表名,因为Excel公式在单个表中起作用。但是,DAX在包含许多表的数据模型上工作,所以,我们必须指定表名,因为不同表中的两列可能具有相同的名称。
DAX中的许多功能与等效的Excel功能以相同的方式工作。例如,IF函数在DAX和Excel中的读取方式相同:
Excel IF ( [@SalesAmount] > 10, 1, 0)
DAX IF ( Sales[SalesAmount] > 10, 1, 0)
Excel和DAX的语法不同的一个重要方面是引用整个列的方式。实际上,在[@ProductQuantity]中,@表示"当前行中的值"。在DAX中,无需指定一个值必须来自当前行,因为这是该语言的默认行为。在Excel中,我们可以通过删除*@ *符号来引用整个列(即该列中的所有行)。您可以在图1一6中看到这一点。
图1-6 在Excel中可以通过在列名之前省略@符号来引用整个列AllSales列的值在所有行中都相同,因为它是SalesAmount列的总计。换句话说,在当前行中的列的值与整个列的值之间在语法上存在差异。
DAX是不同的。在DAX中,这就是您编写*AllSales *的表达式,如图1一6 :
AllSales := SUM ( Sales[SalesAmount] )
检索特定行某列的值与使用整列之间在语法上没有区别。DAX理解我们要对列的所有值求和,因为我们在聚合器(在本例中为SUM函数)中使用了列名,将列名作为参数传递。因此,尽管Excel需要明确的语法来区分要检索的两种类型的数据,但DAX会自动进行歧义消除。至少在开始时,这种区分可能会造成混淆。
Excel和DAX:两种功能语言
两种语言相似的一个方面是Excel和DAX都是功能语言。功能语言基本上是由函数调用的表达式组成。在Excel和DAX中,语句、循环和跳转的概念不存在,尽管它们在许多编程语言中都是通用的。在DAX中,一切都是表达式。对于使用不同语言的程序员来说,语言的这一方面通常是一个挑战,但是对于Excel用户而言,这一点都不奇怪。
DAX中的迭代器
迭代器的概念可能对您来说是一个新概念。在Excel中工作时,您一次只能执行一次计算。前面的示例表明,要计算销售总额,我们创建一个包含价格乘以数量的列。然后,作为第二步,我们对其求和以计算总销售额。然后这个数字才能用作计算每个产品销售百分比的分母。
使用DAX,您可以使用迭代器在单个步骤中执行相同的操作。迭代器完全按照其名称的含义进行操作:迭代表并在表的每一行上执行计算,将结果汇总以产生所请求的单个值。
使用前面的示例,我们现在可以使用SUMX迭代器计算所有销售额的总和:
AllSales :=
SUMX (
Sales,
Sales[ProductQuantity] *
Sales[ProductPrice]
)
这种方法揭示了优点和缺点。优点是我们可以在一个步骤中执行许多复杂的计算,而不必担心添加只会对特定公式有用的列。缺点是,与使用Excel进行编程相比,使用DAX进行编程的视觉效果更差。
确实,您没有看到计算价格乘以数量的列;它仅在计算的生命周期中存在。
正如我们将在后面解释的那样,我们可以创建一个计算列来计算价格乘以数量的乘积。
但是,这样做并不是一个好习惯,因为它会占用内存,并且可能减慢计算速度,除非如第18章 " 优化VertiPaq "所述,您可以使用DirectQuery和聚合。
DAX需要理论
让我们清楚一点:DAX首先需要学习理论的事实与编程语言之间没有区别。这是心态上的差异。面对要解决的问题,您可能习惯于在网络上搜索要解决的方案的复杂公式。使用Excel时,您可能会发现一个几乎可以满足您需要的公式。您可以复制公式,根据需要对其进行自定义,然后使用它,而不必担心它的工作原理。
但是,这种方法在Excel中有效,却不适用于DAX。您需要学习DAX理论并彻底了解评估上下文如何工作,然后才能编写好的DAX代码。如果您没有适当的理论基础,则会发现DAX要么计算像变魔术似的计算,要么计算没有意义的奇怪数字。问题不在于DAX,而是您尚未完全了解DAX的工作原理。
幸运的是,DAX背后的理论仅限于几个重要概念,我们将在第4章 " 理解评估环境 "中进行解释。当您到达该章时,请做好一些深入学习的准备。掌握了这些内容之后,DAX对你来说将不再有秘密,而学习DAX则主要是获得经验。记住:了解是成功的一半。因此,除非您精通评估上下文,否则请不要尝试进一步。
网友评论