CALCULATE
在已修改的筛选器上下文中计算表达式。
注意
还提供了 CALCULATETABLE 函数。 它执行完全相同的功能,只不过它修改了应用于返回表对象的表达式的筛选器上下文。
语法
CALCULATE(<expression>[, <filter1> [, <filter2> [, …]]])
parameters
术语 | 定义 |
---|---|
表达式 | 要进行求值的表达式。 |
filter1, filter2,… | (可选)定义筛选器或筛选器修饰符函数的布尔表达式或表表达式。 |
用作第一个参数的表达式在本质上与度量值相同。
筛选器可为:
- 布尔筛选表达式
- 表筛选表达式
- 筛选器修改函数
如果有多个筛选器,可以使用 AND (&&) 逻辑运算符来计算这些筛选器,这意味着所有条件都必须为 TRUE,或使用 OR (||) 逻辑运算符来计算,这意味着只要一个条件为 true 即可。
布尔筛选表达式
布尔表达式筛选器是计算结果为 TRUE 或 FALSE 的表达式。 必须遵守下面几项规则:
- 可以引用单个表中的列。
- 它们不能引用度量值。
- 它们不能使用嵌套的 CALCULATE 函数。
从 Power BI Desktop 的 2021 年 9 月版本开始,以下内容同样适用:
- 它们不能使用扫描或返回表的函数,除非作为参数传递给聚合函数。
- 它们可以包含返回标量值的聚合函数。 例如:
Total sales on the last selected date = CALCULATE ( SUM ( Sales[Sales Amount] ), 'Sales'[OrderDateKey] = MAX ( 'Sales'[OrderDateKey] ) )
表筛选表达式
表表达式筛选器将表对象应用为筛选器。 它可以是对模型表的引用,但更有可能是返回表对象的函数。 可使用 FILTER 函数应用复杂的筛选条件,包括不能由布尔筛选表达式定义的条件。
筛选器修饰符函数
通过筛选器修饰符函数,不仅仅可以添加筛选器。 它们还在修改筛选器上下文时为你提供额外的控制。
函数 | 用途 |
---|---|
REMOVEFILTERS | 删除所有筛选器,删除表的一列或多列中的筛选器,或者删除单个表的所有列中的筛选器。 |
ALL1、ALLEXCEPT、ALLNOBLANKROW | 删除一列或多列中的筛选器,或者删除单个表的所有列中的筛选器。 |
KEEPFILTERS | 添加筛选器,但不删除相同列上的现有筛选器。 |
USERELATIONSHIP | 在相关列之间建立非活动关系,此时活动关系将自动变为非活动状态。 |
CROSSFILTER | 修改筛选器方向(从双向到单向,或从单向到双向)或禁用关系。 |
1 ALL 函数及其变体既充当筛选器修饰符,又充当返回表对象的函数。 如果工具支持 REMOVEFILTERS 函数,则最好用它来删除筛选器。
返回值
作为表达式结果的值。
备注
提供筛选表达式后,CALCULATE 函数将修改筛选器上下文来对表达式求值。 对于每个筛选表达式,当筛选表达式未包装在 KEEPFILTERS 函数中时,有两种可能的标准结果:
- 如果列(或表)不在筛选器上下文中,则将向筛选器上下文添加新的筛选器来对表达式求值。
- 如果列(或表)已在筛选器上下文中,则新筛选器将覆盖现有筛选器以计算 CALCULATE 表达式。
使用不包含筛选器的 CALCULATE 函数可实现特定要求。 它会将行上下文转换为筛选上下文。 当需要在行上下文中对汇总模型数据的表达式(而非模型度量值)求值时,这是必需的。 在计算列公式中或在计算迭代器函数中的表达式时,可能会出现这种情况。 请注意,当模型度量值用于行上下文时,上下文转换是自动进行的。
在已计算的列或行级安全性 (RLS) 规则中使用时,不支持在 DirectQuery 模式下使用此函数。
示例
“销售”表的下列度量值定义将得到收入结果,但仅针对颜色为蓝色的产品。
可将本文中的示例与 Adventure Works DW 2020 示例模型结合使用。 若要获取模型,请参阅 DAX 示例模型。
Blue Revenue =
CALCULATE(
SUM(Sales[Sales Amount]),
'Product'[Color] = "Blue"
)
类别 | Sales Amount | 蓝色产品的收入 |
---|---|---|
Accessories | ¥1,272,057.89 | ¥165,406.62 |
Bikes | ¥94,620,526.21 | ¥8,374,313.88 |
Clothing | ¥2,117,613.45 | ¥259,488.37 |
组件 | $11,799,076.66 | ¥803,642.10 |
总计 | ¥109,809,274.20 | ¥9,602,850.97 |
CALCULATE 函数会计算修改后的筛选器上下文中“销售”表的“销售额”列的总和 。 新筛选器将添加到“产品”表的“颜色”列中,或者该筛选器将覆盖已应用于该列的所有筛选器 。
“销售”表的下列度量值定义会得出销售额与所有销售渠道的销售额之比。
通道 | Sales Amount | 占所有渠道的收入的百分比 |
---|---|---|
Internet | $29,358,677.22 | 26.74% |
Reseller | $80,450,596.98 | 73.26% |
总计 | ¥109,809,274.20 | 100.00% |
Revenue % Total Channel =
DIVIDE(
SUM(Sales[Sales Amount]),
CALCULATE(
SUM(Sales[Sales Amount]),
REMOVEFILTERS('Sales Order'[Channel])
)
)
DIVIDE 函数将“销售”表中“销售额”列值(在筛选器上下文中)之和除以修改后的筛选器上下文中的同一表达式 。 CALCULATE 函数使用 REMOVEFILTERS 函数修改筛选器上下文,后者是一个筛选器修饰符函数。 它会从“销售订单”表的“渠道”列中删除筛选器 。
下面的“客户”表计算了列定义按忠诚度将客户分为几类。 这是一个很简单的场景:当客户带来的收入少于 ¥2500 时,被归类为“低”忠诚度;否则为“高” 。
Customer Segment =
IF(
CALCULATE(SUM(Sales[Sales Amount]), ALLEXCEPT(Customer, Customer[CustomerKey])) < 2500,
"Low",
"High"
)
在本例中,行上下文被转换为筛选器上下文。 这称为上下文转换。 ALLEXCEPT 函数从“客户”表的所有列(CustomerKey 列除外)中删除筛选器 。