请升级到MicrosoftEdge以使用最新的功能、安全更新和技术支持。
本文仅对DAX中最重要的概念进行基本介绍。其中介绍了DAX适用的所有产品。某些功能可能不适用于某些产品或用例。请参阅产品文档,它介绍了DAX的特定实现。
DAX公式在度量值、计算列、计算表和行级别安全性中使用。
度量值是动态计算公式,其结果会根据上下文更改。度量值在支持使用多个属性(如PowerBI报表或Excel数据透视表或数据透视图)组合和筛选模型数据的报表中使用。度量值是通过使用模型设计器中的DAX公式栏来创建的。
度量值中的公式可以使用通过自动求和功能自动创建的标准聚合函数(如COUNT或SUM),你也可以通过使用DAX公式栏来定义自己的公式。命名度量值可作为参数传递给其他度量值。
无论客户端是什么,都会对结果中的每个单元格运行单独的查询。也就是说,数据透视表中行标题和列标题的每种组合,或PowerBI报表中切片器和筛选器的每种选择,都会生成不同的数据子集,并根据该子集计算度量值。例如,使用这个非常简单的度量值公式:
TotalSales=SUM([SalesAmount])当用户将TotalSales度量值放入报表中,然后将“产品”表中的“产品类别”列放入筛选器中时,将计算并显示每个产品类别的“销售额”总和。
与计算列不同,度量值的语法包括公式前面的度量值名称。在刚才提供的示例中,名称TotalSales出现在公式之前。创建度量值后,名称及其定义将显示在报表客户端应用程序字段列表中,并且根据透视和角色,可供模型的所有用户使用。
计算列是这样的列:在模型设计器中添加到现有表,然后用于创建定义列值的DAX公式。当计算列包含有效的DAX公式时,输入公式后就会立即为每行计算值。然后,将值存储在内存中数据模型中。例如,在“日期”表中,在公式栏中输入公式后:
计算表是一个基于公式表达式的计算对象,派生自同一个模型中的所有或部分其他表。DAX公式定义表值,而非从数据源中查询值并将值加载到新表的列中。
计算表在角色扮演维度中非常有用。例如“日期”表,如OrderDate、ShipDate或DueDate,具体取决于外键关系。通过为ShipDate显式创建计算表,将获得可用于查询的独立表,该表与任何其他表一样完全可操作。在配置筛选的行集或其他现有表中列的子集或超集时,计算表也很有用。这样可以在创建表的变体以支持特定方案时保持原始表不变。
计算表支持与其他表之间的关系。计算表中的列具有数据类型、格式设置,并能归属于数据类别。可以像对任何其他表一样,对计算表进行命名、显示或隐藏。如果计算表从其中提取数据的任何表刷新或更新,则将重新计算计算表。
使用行级别安全性时,DAX公式的计算结果必须为TRUE/FALSE布尔值条件,以定义特定角色成员的查询结果可以返回哪些行。例如,对于“销售”角色的成员,具有以下DAX公式的“客户”表:
=Customers[Country]="USA"“销售”角色的成员将只能查看美国客户的数据,而聚合(如SUM)只返回美国客户的数据。行级别安全性在Excel中的PowerPivot中不可用。
使用DAX公式定义行级别安全性时,将创建一个允许的行集。这不会拒绝对其他行的访问;相反,它们只是不作为允许的行集的一部分返回。其他角色可允许访问DAX公式所排除的行。如果用户是其他角色的成员,且该角色的行级别安全性允许访问该特定行集,则该用户可以查看该行的数据。
可以在SQLServerManagementStudio(SSMS)和DAXStudio(daxstudio.org)等开放源代码工具中创建和运行DAX查询。不同于DAX计算公式只能在表格数据模型中创建,DAX查询也可以针对AnalysisServices多维模型运行。与多维数据表达式(MDX)查询相比,DAX查询通常更易于编写,而且效率更高。
DAX查询是一个语句,类似于T-SQL中的SELECT语句。DAX查询的最基本类型是计算语句。例如,
EVALUATE(FILTER('DimProduct',[SafetyStockLevel]<200))ORDERBY[EnglishProductName]ASC在结果中返回一个表,该表仅列出SafetyStockLevel小于200的产品,按EnglishProductName升序排序。
DAX公式对于在计算列和度量值中创建计算以及使用行级别安全性保护数据方面非常重要。要为计算列和度量值创建公式,请使用模型设计器窗口顶部的公式栏或DAX编辑器。要为行级别安全性创建公式,请使用“角色管理器”或“管理角色”对话框。本部分中的信息旨在帮助你开始了解DAX公式的基础知识。
DAX公式可以很简单,也可以非常复杂。下表显示了一些可以在计算列中使用的简单公式示例。
无论所创建的公式是简单的还是复杂的,都可以按照以下步骤生成公式:
注意
在计算列中,只要输入公式并验证公式,列就会填充值。在度量值中,按Enter键会将度量值定义与表一起保存。如果公式无效,将显示错误。
在本示例中,我们来看看名为“DaysinCurrentQuarter”的度量值中的公式:
此公式包含以下元素:
记忆式键入功能通过为您提供公式中每个元素的选项,可帮助您输入有效的公式语法。
您可以嵌套函数,这意味着您可以使用一个函数的结果作为另一个函数的参数。在计算列中,最多可以嵌套64个级别的函数。但是,嵌套可能会导致很难创建公式或者排除公式问题。许多函数设计为仅用作嵌套函数。这些函数返回一个表,该表不能直接保存为结果,而必须作为表函数的输入提供。例如,函数SUMX、AVERAGEX和MINX全都要求将表作为第一个参数。
VARTotalQty=SUM(Sales[Quantity])ReturnIF(TotalQty>1000,TotalQty*0.95,TotalQty*1.25)在本示例中,可以将TotalQty作为命名变量传递给其他表达式。变量可以是任何标量数据类型,包括表。在DAX公式中使用变量的功能非常强大。
DAX支持以下数据类型:
表格数据模型还包括表数据类型,作为许多DAX函数的输入或输出。例如,FILTER函数采用表作为输入,并输出仅包含满足筛选条件的行的另一个表。通过组合表函数与聚合函数,您可以对动态定义的数据集执行复杂计算。
尽管数据类型通常都是自动设置的,但还是需要了解数据类型,尤其是它们如何应用到DAX公式,这一点非常重要。举例来说,公式中的错误或是意外结果通常都是因为对参数中指定的数据类型使用了不该使用的特定运算符而导致的。例如,公式=1&2返回结果为12的字符串。但是公式="1"+"2"返回的结果为整数3。
可以在不同的上下文中计算表格模型中的公式,这取决于其他设计元素:
有许多类型的上下文:“行上下文”、“查询上下文”和“筛选上下文”。
例如,假设创建将同一表中的两列(Freight和Tax)的值相加的计算列=[Freight]+[Tax]。此公式仅自动获取指定列中当前行的值。
=[Freight]+RELATED('Region'[TaxRate])此公式从Region表中获取当前区域的税率,并将其与Freight列中的值相加。在DAX公式中,您无需了解或指定连接各表的特定关系。
DAX包括对表执行迭代计算的函数。这些函数可以具有多个当前行,其中每个行都有自己的行上下文。实际上,可以利用这些函数创建用于以递归方式对内部和外部循环进行操作的公式。
例如,假设您的模型包含一个Products表和一个Sales表。用户可能想要遍历整个Sales表,该表中全都是涉及多个产品的交易,并且您还要找到在任何一个交易中为每个产品订购的最大数量。
使用DAX,您可以生成返回正确值的单个公式,并且只要用户向表中添加数据,结果就自动更新。
总之,该EARLIER函数存储来自当前运算之前的运算中的行上下文。在任何时候,该函数都在内存中存储两组上下文:一组上下文表示公式的内部循环的当前行,另一组上下文表示公式的外部循环的当前行。DAX自动在两个循环之间馈送值,以便您可以创建复杂的聚合。
“查询上下文”是指为公式隐式检索的数据子集。例如,当用户将度量值或字段放入报表时,引擎将检查行标题、列标题、切片器和报表筛选器,以确定上下文。然后,对模型数据运行必要的查询以获取正确的数据子集,进行公式定义的计算,接着在报表中填充值。
由于上下文会根据放置公式的位置而更改,因此公式的结果也会更改。例如,假设你创建一个对“销售”表“利润”列中的值求和的公式:=SUM('Sales'[Profit])。如果在“销售”表中的计算列中使用此公式,则该公式的结果对于整个表将是相同的,因为公式的查询上下文始终是“销售”表的整个数据集。结果将包含所有区域、所有产品、所有年份等的利润。
但是,用户通常不希望看到数百次相同的结果,而是希望获得特定年份、特定国家/地区、特定产品或这些条件任意组合下的利润,然后获取总计。
在报表中,通过筛选、添加或删除字段以及使用切片器来更改上下文。对于每个更改,为将在其中计算度量值的查询上下文。因此,对于每个单元,在不同的“查询上下文”中计算在度量值中使用的相同公式。
通过在公式中使用参数,为列或表中允许存在的值集指定筛选约束时,将添加“筛选上下文”。基于其他上下文(如行上下文或查询上下文)应用筛选上下文。
在创建一个DAX公式时,首先会测试该公式的语法是否有效,然后测试该公式以确保其包含的列和表的名称位于当前上下文中。如果找不到该公式指定的任一列或表,则将返回错误。
如前所述,通过使用模型中的可用表、表之间的所有关系和所应用的所有筛选器来确定验证(和重新计算操作)期间的上下文。
上下文是一个很有用的概念,但也可能导致很难排除公式问题。我们建议您从简单的公式和关系入手,了解上下文的工作原理。下一节提供了一些示例,说明公式如何使用不同类型的上下文来动态返回结果。
DAX语言在公式中使用四种不同类型的运算符:
表格数据模型中的表与Excel表类似,但在处理数据和公式的方式上有所不同:
可以通过名称来引用任何表和列。例如,下面的公式说明如何通过使用“完全限定”的名称来引用两个表中的列:
使用关系时,必须遵守以下公式设计规则:
处理(刷新)使用外部数据源中的新数据更新模型中的数据。
“重新计算”是对公式结果进行更新的过程,用于反映对公式本身的任何更改以及基础数据中的更改。重新计算会以下列方式影响性能:
处理和重新计算对行级别安全性公式没有影响,除非重新计算的结果返回不同的值,从而确定行是否可由角色成员查询。
并非所有函数都在早期版本的SQLServerAnalysisServices和Excel中受支持。
如果在定义公式时遇到错误,公式可能会包含“语法错误”、“语义错误”或“计算错误”。
语法错误最容易解决。它们通常涉及缺少括号或逗号。
当语法正确,但引用的值或列在公式的上下文中没有意义时,会发生另一种类型的错误。此类语义和计算错误可能是由于下列任何问题导致的:
在前四种情况中,DAX标记包含无效公式的整个列。在最后一种情况中,DAX会灰显该列,以便指示该列处于未处理的状态中。