如果包含计算列的表与另一个表相关,则在每行中,可以使用 RELATED 函数从另一个表中的列中检索相应的值。...想要透彻理解 CALCULATE 的工作原理,应该时刻牢记它按顺序执行四个基本步骤。 将现有上下文(行上下文或查询上下文,或其他筛选上下文)全部转换为筛选上下文。...从行上下文到筛选上下文的转换,是通过对表中的每一列创建一个筛选器来实现的,这些筛选器将对应的列中的值指定为当前行中的列的值(请记住,行上下文始终与单个行相关)。结果是生成了一个选择当前行的筛选上下文。...或者,您可以使用 GENERATEALL,它包含这样的行,但在表表达式的列中包含空白值。...在计算列中使用时,将在每行中添加新的筛选器以选择该行。在新上下文中计算相关表时,关系会传递筛选器,并且相关表将被筛选为仅链接到当前表的行。
然后它通过在颜色上创建筛选上下文来计算具有相同颜色的所有行的 Amount 总和。...相反,它使用集群中的所有列创建筛选上下文,筛选集群中存在的值。...,一定要注意它的筛选器并不仅仅是集群标头,它包含表上的所有列。...在评估新列期间,SUMMARIZE 对集群进行迭代并生成: 包含簇头的行上下文; 一个筛选上下文,包含集群中的所有列,包括集群标题。 这种独特的行为给本来就很复杂的函数增加了一些混乱。...它只会造成一些混乱,因为当您在 SUMMARIZE 中使用 CALCULATE 时,您不仅会更改筛选上下文,还会对簇标题中的所有列调用上下文转换。
这里关键要理解Calculate函数的的计值流,它的filter参数,会在现有的计算上下文(如这里的“菜品名称”筛选上下文)中进行计算,所以,max会取到当前“菜品名称”下的最大日期,最终得出正确答案,...所有显式筛选器参数在这个初始环境中独立计算,计算完成后,CALCULATE开始构建新的筛选上下文。...3、CALCULATE 执行上下文转换 CALCULATE 使用列在原始行上下文中的当前值,为正在迭代的所有列提供一个具有唯一值的筛选器。...值得注意的是此筛选器可能包含也可能不包含单个行,因为上下文转换并不保证新的筛选上下文只包含一行。如果没有正在生效的行上下文,则跳过此步骤。...5、CALCULATE 将步骤 1 的结果应用于步骤4 之后生成的新筛选上下文 一旦发生了上下文转换,这些筛选器参数就会应用到新的筛选上下文中覆盖转换生成的上下文。
在这种场景下,定义这类计算项,就需要使用其输入的度量值。获取输入到计算组的度量值需要使用dax函数SELECTEDMEASURE()。 下面创建一个 时间维度计算组,并在其创建三个计算项: ?...- 1, BLANK () ) 此时,该模型中就存在两个计算组,如果返回页面,将 时间维度计算组 表列[Name1]加入至切片器后,当前页面的度量值便同时受两个计算组所控制,如下 ?...([收入], SAMEPERIODLASTYEAR ( '日期表'[Date] ) ) 需要注意的是,虽然也可以像其他表列一样,在DAX中直接引用其计算组表的名称列,但与其他列筛选并不相同: 1、在DAX...中直接引用其计算项的名称,进行列筛选,该筛选只对度量值起作用 2、当模型中存在多个计算组时,其对度量值的重新定义改写存在先后顺序(改写的先后顺序会影响计算结果,本案例由于其特殊性,其不同的顺序计算结果相同...因此上面三种写法是等价的。 3、同一计算组,多个计算项通过CALCULATE嵌套筛选,内层筛选会覆盖外层筛选。
一个特别实用的动作是,可以在记事本里分析和反查这些列是否合理。如下: 这可以非常快地帮助我们发现问题。 但问题来了,我们发现有的表有很多列,是否可以直观的写下有多少列呢?...直到发现它的问题: 只要报表界面上有任何筛选器,都会导致这个错误。仔细阅读错误信息: COLUMNSTATISTICS () 不能与筛选上下文一起使用。...仔细思考一下原因,由于 COLUMNSTATISTICS 是用来获得模型信息的,并不是用来进行计算的,因此,DAX 引擎将其隔绝在筛选上下文之外是有道理的。 如何进行修复呢?...既然错误是:不能与筛选上下文一起使用。那么可以清除掉所有的筛选上下文即可。 最后得到了带有这种保护的版本。...当我们第一次这样尝试的时候,会触发一个错误: 不能与筛选上下文一起使用。
在任何上下文中引用度量值时,因为引用的度量值在CALCULATE函数内部执行它的DAX代码。 3 计算列中的上下文转换 3.1 简单应用 单层行上下文的转换非常直观,相信都能理解。...那下面就通过一个简单例子来介绍下,具体如下图所示: 对于计算列SumOfValue,由于在计算列的初始计值环境里不存在任何筛选器,所以筛选上下文里的数据为所有数据,故导致每一行的结果都是总计值。...3.2 计值顺序 下面再来看一个例子,假设现在需要添加一个计算列,计算当前类别对应的所有值中的最大值,结果如下图所示: 其中使用到的计算列表达式如下: MaxValueOfCategory = CALCULATE...(1)ALLEXCEPT用作CALCULATE调节器时,将移除第一参数指定的表的扩展表中除所指定列之外的其余列上的所有筛选器。...值得注意的是,由行上下文转换而来的筛选器也有可能会不遵守筛选器交互的最基本原则,例如某层行上下文中使用了KEEPFILTERS函数,那么其转换而来的全部筛选器的交互方式将变为相交。
="B") ) 今天我们再来深入分析“覆盖筛选条件”的情况,真正搞清楚它的计算过程,以及与增加筛选条件的相同的原理却结果存在较大差异的原因,从而进一步强化对CALCULATE函数的理解!...下面,我们就用calculate函数的完整计值流——备,拷,转,调,叠,算,还原一下度量[B_覆盖原型]的计算过程,看看和你理解的是否有差别。...第2步:拷——拷贝原始上下文 这里的原始上下文即透视表的两项:销售、产品,如在计算“大海/A”的销量时,“销售”筛选器的当前值为“大海”,而“产品”筛选器的当前值为“A”。...第3步:转——将行上下文转换为筛选上下文 这里没有行上下文,所以没有触发这个步骤的相关过程,跳过不用管。 第4步:调——调节器调整上下文的影响行文 这里没有调节器,所以这个步骤也跳过不用管。...大家可以试着将“ ALL('产品销售表'[产品])”改为“ ALL('产品销售表')”,然后分析一下这个计算过程和结果,去理解一下ALL(表)和ALL(列)的差别。
一个使用了CALCULATE函数的公式,到底是怎么样计算得到它的结果的?如果没有真正搞懂CALCULATE函数计值流(计算过程)的话,即使这个公式很简单,也可能会无法理解!...比如下面这个例子,建一个计算列(带行上下文)写的简单公式,如果你把它的计算过程搞清楚了,相信你对CALCULATE函数的理解又进了一大步。...这个公式的计算过程到底是怎样的? 建议自己先尝试画一下计算过程,看看跟我下面的分析是否一致。 前面,我写过关于CALCULATE函数计值流的文章:《666,Calculate计值流记不住?...其中,关于CALCULATE函数的计值流,提炼为“备、拷、转、调、叠、算”: 下面,我们再用这个方法,来剖析这个计算列的计算过程: 1、“备”:准备显式筛选器 显然,这个公式里只有一个显式筛选器参数...所以,对于每一行,都会筛选出产品大类为文具的表,这个表包括“产品名称”、“产品大类”、“销售额”三列,即会生成3个对应的筛选器,且这些筛选器对应的值为筛选结果表中列的所有值: 2、“拷”:拷贝原有筛选上下文
当作为CALCULATE调节器使用时,ALLSELECTED将还原其参数上的最后一个影子筛选上下文。 这两句话值得我们详细解释。...因为最后一个影子筛选上下文包含3个地区,所以切片器选择的所有地区再次可见。 这个简单的例子帮助我们引入了影子筛选上下文的概念。...如果需要保留之前的筛选上下文,就不能只依靠ALLSELECTED。保留之前的筛选上下文的CALCULATE调节器是KEEPFILTERS。...而是指示迭代函数在迭代表的过程中,每当发生上下文转换时,将KEEPFILTERS作为隐式CALCULATE调节器应用到度量值中。虽然查询返回所有的地区,但计算最终结果时,只考虑了所选的地区。...在这种情况下,ALLSELECTED将恢复任何列上的最后一个影子筛选上下文。 请记住,当且仅当列被包含在任何影子筛选上下文中时,才会发生这种情况。如果仅通过显示筛选器筛选列,那么筛选器保持不变。
不过这些在PBI中将不会存在,PBI将通过模型的建立,表与表之间的关联不再与数据呈现的物理位置有关,只需要理解“上下文”这个概念。...具体操作如下: 在PQ编辑器中对查询生成的资产负债表选择除公司代码、报告日期之外的其他列后右击,选择逆透视列,完成后更改下列名,如下: ? ?...利润表和现金流量表也按这样操作,最后三张财务报表列数完全相同,都是四列,分别为公司代码、报告日期、科目、值。...] 年季名称 = [年]&[季度名称] 在自动生成的日期建立这些字段主要是便于后期筛选和计算。...依次将相关度量值,加入值,项目名称加入到行 ? 同时将科目表的类型字段,加入到该矩阵的筛选器,并筛选资产 ? 2. 负债项目与资产项目一样,可直接将矩阵复制一个,将筛选器改为权益 ?
3.最后一个基本度量值是计算12个月滚动销售额,使用 DAX 筛选器函数 CALCULATE 和时间智能函数 DATESINPERIOD 的组合。...如果你需要有关 DAX 筛选器函数的更多信息,请参见第4章。在此过程中,我们将根据我们的特定需求调整此基本计算,代码如下。...此处,还可以使用其他DAX函数,如SELECTEDVALUE,它检测列中是否只选择了一个值。但是,你仍应使用Code列,以避免在有人决定更改描述时必须更改DAX代码。...第一列包含指示标签类型(国家/地区、零售类型或组)位于行中的指示器,第二列包含三列中的值。第一列可用于选择标签类型。然后,DAX度量值将实现与三个原始表之一的动态关系。...TREATAS获取值列表,并将其作为筛选器应用于另一列,这两列不需要以任何方式相关,你可以将其解释为创建虚拟关系的TREATAS。
2 使用TREATAS函数转移筛选器 首选的也是最好的做法是,使用TREATAS将Advertised Brands表的筛选器转移到其他表上。...借助TREATAS,我们可以改变Advertised Brands表的数据沿袭,使其可以作为CALCULATE的筛选器参数,并将其筛选器作用于整个数据模型。...因为它复用了Sales Amount度量值,避免了重写代码,并且不需要迭代Sales表来执行查询。 3 使用INTERSECT函数转移筛选器 获得相同结果的另一种做法是使用INTERSECT函数。...中使用Sales表作为筛选器是很危险的。...因此,只筛选三个列是更好的选择。此外,这里不需要使用KEEPFILTERS,因为SUMMARIZE已经保留了品牌、年份和月份在当前筛选上下文中的可见值。
需要呈现的结果如下图所示: 图1 在同一个客户的所有订单中,Order Position包含每个订单的相对位置 1 计算订单号小于或等于当前订单号的所有订单数量 订单号是唯一的,它的值会随着订单的增加而增加...在CALCULATE中,它使用订单号和由计算列生成的上下文转换作为筛选器。对于Sales表的每一行,引擎必须筛选Sales表本身。因此,它的复杂度就是Sales表行数的平方值。...因为Sales表包含10万行,所以总的复杂度是10万乘10万,结果就是100亿。最终的结果就是这个计算列需要花费数小时来计算。在更大的数据集中,它足以让任何服务器奔溃。...2 使用组合表 创建一个包含CustomerKey和Order Number的所有组合的表,以避免使用CALCULATE执行计算开销更大的上下文转换。...然后value在当前筛选上下文中计值,将得到的结果与列表中的值进行比较,根据排名规则order和ties的设置,返回最终排名。
我们可以将ALL用作迭代函数的参数,例如SUMX和FILTER,也可以将ALL用作CALCULATE函数中的筛选器参数。CALCULATE函数在第5章中会介绍。...ALLEXCEPT主要作为CALCULATE函数的一个筛选器参数用于高级计算中,很少采用这种较简单的公式。因此,为了完整起见,我们在这里介绍了它的作用,在后面的学习中它才会派上用场。...在学习了CALCULATE函数和筛选上下文之后,你将能够使用更短、更有效的语法编写相同的计算表达式。...VALUES函数返回在当前筛选器中计算的列的不同值。如果在计算列或计算表中使用VALUES或DISTINCT函数,则它们与ALL函数的行为相同,因为没有生效的筛选器。...在第4章中,我们将介绍计值上下文和CALCULATE函数。在学习了CALCULATE函数之后,你可能会重新阅读本文,使用表函数作为CALCULATE函数的参数,从而充分利用它们的潜力。
其实道理是一样的,现在我们面对的表格就好比阅读理解的语段,只有理解好它们的逻辑,才能写出正确的表达式。表的构成很简单,列和行。所以它的上下文分为两种,筛选上下文(即列的上下文)和行上下文。 ?...筛选上下文最容易理解,是纵向的列筛选条件。比如下面的表中销售量2974的筛选上下文是"2016年-第2季度-拿铁",即对日期列和咖啡种类列的筛选。 ? 行上下文,顾名思义,是要横向的看。...以第一行卡布奇诺行为例,在计算咖啡数量时,行上下文是原材料表中的当前行,而计算的公式sum('咖啡数据'[数量])是求数据表中的[数量]列的和。...关键的语法就在这里了,行上下文不会自动转换成筛选上下文,如果需要转换,要使用Calculate。请记住这条规则。我们试一下把公式外套一个Calculate。...我们还以第一行举例,Calculate这个超级力量函数就好比模型的启动键,当赋予Calculate时,关系模型的阀门启动,数据信号顺流而下,这个数据信号是将行上下文转换成了筛选上下文,按照当前行中咖啡种类卡布奇诺这个筛选条件对数据表进行筛选
[1240] ALLSELECTED函数 ALLSELECTED函数,被微软划分为“筛选”类函数,隶属于“表函数”。其用途,常常是用来计算或者显示明面上的筛选影响,而忽略其行上下文的影响。...作为ALL函数系列家族中的一员,它并不像其他ALL系列函数那样,可以称得上是个性鲜明。...列:(可选项可重复)不能是表达式,现有列的名称。 注意:要么是表,要么是列;如果是多列,必须在同一表中。返回结果 不带任何列或行上下文的上下文。...切片器这种,通过一些摆在明面的控制器,来影响计算,筛选的条件,这里称之为显性筛选,即肉眼可见的控制。 例子 模拟数据: [1240] 这是白茶随机模拟的一份数据,很简单。...无论切片怎么动,ALL函数遵循行上下文的隐性筛选,不受切片器联动。ALLSELECTED函数遵循显性控制,忽略行上下文,占比始终发生变化。
(使用辅助表,还可以分别创建三个度量值,与视觉对象的功能组合起来使用) 然后将辅助表的指标名称列加入到切片器视觉对象,这样就可以让用户通过该切片器控制度量值[指标切换]值的显示。...正因为计算组会影响当前页面所有受[Name]列筛选的度量值,因此,原使用辅助表构造的值也会发现变化,如下: ?...如表1中的度量值虽然是通过辅助表与DAX重写了,但是由于计算组表[Name]列中的“收入”是选定状态,在交互筛选的作用下,表1表2中的度量值都会传入计算组,然后返回收入计算项定义的值(表达式),也就是显示...事实上,表1中的度量值[指标切换]等价于 CALCULATE([指标切换],'指标名称计算组'[Name]="收入") 表2中的度量值[指标切换]等价于 CALCULATE([值],'指标名称计算组'...列“收入”项所指向的定义表达式(即度量值[收入])所替换,也就是说上面两个度量值最终都被替换成了[收入] 可以将计算项理解为 特殊的自定义函数 ,其输入参数为度量值(取决于该度量值是否受计算组表列的筛选影响
这里我们推荐使用 . 分隔符命名法。其约定在于:将主要的事情放在前面,将限定的部分放在后面,与 CALCUALTE 的写法类似。...这是有原因的: 从排序上看,相关的度量值会排列在一起,便于使用; 从语义上看,与 CALCULATE 的语义达成一致,便于识别含义。 其次,注意动态性的保持与屏蔽。...在本例中,当用户选择不同部门或职能时,那么所有的计算应该在该限定下完成,因此,我们必须保持这个动态性。 这就要求我们在使用 ALL 函数时,尽量作用到列,而不是一下将这个表都 ALL 掉。...度量值讲解 KPI.人数.离职.当期 = COUNTROWS( VALUES( Data[工号] ) ) 对人数的计算,应该以员工编号作为唯一标识,因此使用该列,同时,我们希望这个计算保持可被筛选的特性...第 5 行,MAXX 创建针对于 ‘Date’ 的迭代所处的筛选上下文是 进入 CALCULATE 前的筛选上下文,如 2019年3月。 第 7 行,由 DAX 引擎添加。
图3中第2行的xmSQL查询如下图(图5)所示: CALCULATE函数的表筛选器会在查询计划中导致这种副作用,因为筛选器的语义包括Sales表扩展表的所有列。...2.1.2 优化后 这里使用列筛选器对度量值进行优化。因为筛选表达式使用了两列,所以行上下文需要一个只包含这两列的表,作为更高效的CALCULATE函数的筛选器参数。...采用这种优化措施的依据是查询计划可以在存储引擎中创建更高效的计算,从而避免使用表筛选器的语义向公式引擎返回额外的列。...下图(图9)是图7中第2行的xmSQL查询: 数据缓存中不再包含Quantity列和Net Price列,它的基数对应DAX结果的基数。这是理想条件下的最小物化。...使用列而不是使用表所为筛选条件是实现这一效果的关键步骤。 2.1.3 小结 (1)在可能的情况下,CALCULATE/CALCULATETABLE函数的筛选器参数应该始终筛选列,而不是表。
高级筛选器 Filter函数 度量值工作的两大核心步骤是筛选和计算,筛选函数是制定计算的范围,聚合函数的用途是计算。...左手漏斗筛选器,右手智能计算器,随心所欲的设计你的筛选和计算,Master of Power BI指日可待。这一节我们就来学习最强大的筛选函数Filter。 ?...就好像求1+1=2,我们没有必要用电脑来计算。 ? 先说说Calculate的局限性,在Calculate中的直接筛选条件里我们只能输入[列]=固定值(等运算符同样适用)这种类型的条件。...它们与其他函数的主要区别就是在工作的时候可以意识到它所指的是哪一行, 我们把这个工作叫做创造行上下文。 需要注意的是,迭代函数很强大,但是因为它强大的计算能力,我们使用的时候要格外小心。...前面提到Calculate的筛选条件只能执行[列]=固定值这一类的计算,当应对这一类筛选运算时,简单的Calculate运算起来最快。
领取专属 10元无门槛券
手把手带您无忧上云