FIRSTNONBLANK / LASTNONBLANK 扫描一个表,逐行计算第二参数,并返回不为空的第二参数所对应的表的最后一个/第一个值。与 MIN/MAX 不同的是,它们可以根据你指定的逻辑进行计算,且支持文本格式。
FIRSTNONBLANK / LASTNONBLANK
FIRSTNONBLANK ( < ColumnName>, < Expression> ) LASTNONBLANK ( < ColumnName>, < Expression> )
<ColumnName>在当前筛选上下文中每行计值<Expression>,返回结果不为空的第一个或最后一个<ColumnName>的值。其行为类似于 SUMX 或其他类似函数,因为它们都是迭代函数
:为列参数设置行上下文,然后使用该行上下文计值表达式。
第一参数直接引用列名,不需要借助任何表函数,因为它等价于:
CALCULATETABLE ( DISTINCT ( <ColumnName> ) )
如何判定第一个值和最后一个值
- 当<ColumnName>是英文文本格式时:
按首字母顺序对第一参数的结果进行排序,FIRSTNONBLANK 返回升序排序的第一个值, LASTNONBLANK 返回最后一个值 - 当<ColumnName>是数字格式时:
按数值顺序对第一参数的结果进行排序,FIRSTNONBLANK 返回升序排序的第一个值, LASTNONBLANK 返回最后一个值 - 当<ColumnName>是日期时间格式时:
按时间顺序对第一参数的结果排序,FIRSTNONBLANK 返回升序排序的第一个值, LASTNONBLANK 返回最后一个值 - 当<ColumnName>是中文文本格式时:
Desktop 按某种特定顺序(偏旁)对第一参数的结果排序,Excel PowerPivot 按首字母顺序排序。Desktop 的排序无法直观判断,建议先通过视觉对象或数据视图内的排序来判断。注意,使用按列排序无法改变函数的排序结果。
最后,FIRSTNONBLANK / LASTNONBLANK 的第一参数经常使用日期列,这使得它在时间智能函数中经常出现,但实际上它支持任何类型的列,因为这两个函数本质上都是迭代函数。
以上图中 Table 的数据为例,如果想要获得销售额不为空的第一个产品经理,有两种写法:
F1 = FIRSTNONBLANK('Table'[地区经理],CALCULATE(SUM('Table'[销售额]))) F2 = FIRSTNONBLANK('Table'[地区经理],SUM('Table'[销售额]))
F1 得到的结果是「杨建」,在 5 个有销售的地区经理中返回了排序最小的那一个,这个计算逻辑是正确的。
F2 的结果也是「杨建」,但这次是从所有的地区经理列表中返回的排序最小值。原因在于 F2 公式中的SUM('Table'[销售额])
忽略行上下文,每个经理都返回相同的结果,使得 FIRSTNONBLANK 在整个经理列表中计算最小值。
由于中文排序的特殊性,这个例子的结果可能会令你困惑,建议先在数据视图或视觉对象中对目标列进行排序,以正确识别真正的最小和最大值。值得注意的是,FIRSTNONBLANK 和 LASTNONBLANK 使用的排序不会被按列排序所覆盖。
迭代函数的上下文转换
如果<Expression>和<ColumnName>共用同一张表的数据,不需要特别处理就可以正常计值。但是当<Expression>使用<ColumnName>所在表以外的其他表时,你必须通过使用 RELATEDTABLE、CALCULATETABLE 或 CALCULATE 进行上下文转换。这是所有与日期相关的计算的最佳实践,而且每次使用单独的日期表时这种情况都很常见。比如要正确地获得给定度量值或表的最后一个非空日期值,你必须使用如下表达式:
LASTNONBLANK ( Dates[Date], CALCULATE ( COUNT ( Inventory[Quantity] ) ) )
它返回在当前筛选上下文中,库存表数量列不为空的最近日期,你也可以用另一个等价公式:
LASTNONBLANK ( Dates[Date], COUNTROWS ( RELATEDTABLE ( Inventory ) ) )
这个表达式返回当前筛选上下文中,库存表中有相关记录的最后一个日期。
可用作 CALCULATE 筛选器的表函数
FIRSTNONBLANK 和 LASTNONBLANK 返回标量值,但同时也可以作为 CALCULATE 函数的筛选器参数,因为本质上它们返回的是单行表。比如:
Units LastNonBlank := CALCULATE ( SUM ( Inventory[UnitsBalance] ), LASTNONBLANK ( 'Date'[Date], CALCULATE ( SUM ( Inventory[UnitsBalance] ) ) ) )
LASTNONBLANK 与 LASTDATE 的区别
FIRSTNONBLANK/LASTNONBLANK 函数接受任何数据类型作为其第一参数,而 FIRSTDATE/LASTDATE 函数则需要列必须使用日期类型。如果日期值所在的列使用了另一种数据类型,你希望获得它在筛选上下文中的第一个或最后一个值时,需要使用 FIRSTNONBLANK/LASTNONBLANK 而不是 FIRSTDATE/LASTDATE,将任何非空表达式作为第二个参数传递。当然,你也可以考虑在这种情况下使用 TOPN 函数。
TopDate := TOPN ( 1, VALUES ( Date[DateKey] ), [Internet Total Sales] )
如果两个或两个以上的日期具有相同的最高销售额,则 TopDate 度量值将报错,因为 TOPN 返回了一个包含一列和两行或更多行的表,不能被转换为标量值。你可以对公式做如下改动:
TopDate := LASTNONBLANK ( TOPN ( 1, VALUES ( Date[DateKey] ), [Internet Total Sales] ), 1 )
理解 LASTNONBLANK 的第二参数
排序规则
如上文所述,你可以对任何数据类型的列使用 FIRSTNONBLANK 和 LASTNONBLANK,但是需要注意数值和文本类型的排序规则有所不同。
现在规则又改了,power bi desktop里中文文本又按首字母顺序排序了,所以f1、f2的计算结果分别应该是楚杰和白德伟。
图1是’销售表’的地区经理列升序排列结果;图2是f1计算结果。
没看懂,为啥第一参数等价于红框的内容。
F1 = FIRSTNONBLANKVALUE(‘Table'[地区经理],CALCULATE(SUM(‘Table'[销售额])))
F2 = FIRSTNONBLANKVALUE(‘Table'[地区经理],SUM(‘Table'[销售额])),
把F1和F2的公式改成上面的公式,放到矩阵当中为什么结果是一模一样啊?
第二参数区分 0 和 BLANK,0 也是非空值,和 1 的效果相同。当第二参数使用 BLANK()时,函数永远返回空值。想问一下,第二参数区别逻辑值FALSE和BLANK吗?,如果第二参数使用返回逻辑值的函数当作参数,TRUE和FALSE的返回结果是一样的吗?
LASTNONBLANK ( Dates[Date], COUNTROWS ( RELATEDTABLE ( Inventory ) ) )返回最后一个非空日期写成这样是不是也是等价的CACULATETABLE(LASTNONBLANK ( Dates[Date], NOT(ISEMPTY(Inventory ) ))
Units LastNonBlank :=
CALCULATE (
SUM ( Inventory[UnitsBalance] ),
LASTNONBLANK (
‘Date'[Date],
CALCULATE ( SUM ( Inventory[UnitsBalance] ) )
)
)是不是也等价于Units LastNonBlank :=
CALCULATE (
SUM ( Inventory[UnitsBalance] ),
CALCULATETABLE(LASTNONBLANK ( Dates[Date], NOT(ISEMPTY(Inventory ) )
)
)
FIRSTNONBLANK / LASTNONBLANK 扫描一个表,逐行计算第二参数,并返回不为空的第二参数所对应的表的最后一个/第一个值。与 MIN/MAX 不同的是,它们可以根据你指定的逻辑进行计算,且支持文本格式。
老师好~~文中说FIRSTNONBLANK / LASTNONBLANK扫描一个表,为啥我感觉是扫描一个表的某一列,然后逐行计算第二参数。
到底是扫描表,还是扫描第一参数中的列?
高老师,为什么我F1得到的结果是楚杰?
上面F1跟F2的结果也跟我测试的不一样,麻烦老师看下什么原因?
老师,请问F2 = FIRSTNONBLANK(‘Table'[地区经理],SUM(‘Table'[销售额])),这个sum忽略行上下文我能理解,但是这个外部筛选上下文也对内部的SUM(‘Table'[销售额])不起作用吗,如果起作用的话,那么应该计算出来的不应该是和上边F1加calculate计算出来的结果一样吗,这个我有点疑惑,还是说这个函数的第二个参数在计值的时候忽略外部筛选上下文
用人名来做这个例子真不好,应该用日期来做列,更好些
是按照列来 计算表达式,看表达式结果为非空的第一个或最后一个列中的值。
通过在PBI DESKTOP里面进行测试文中的两个度量值。发现都是返回的杨建这个值。并非正文所示的那样。经过排序,发现杨建排在第一位的。不是按照字母拼音顺序排序的。
F1 = FIRSTNONBLANK(‘Table'[地区经理],CALCULATE(SUM(‘Table'[销售额])))
F2 = FIRSTNONBLANK(‘Table'[地区经理],SUM(‘Table'[销售额]))
老师,这2个不同,是因为F1中,迭代函数创建的行上下文,被CALCULATE转换成了筛选上下文,而聚合函数是忽略不了筛选上下文的;在F2中,行上下文没有转化,被聚合函数忽略了,所以造成差异吗?
是不是就代表着,计算列以及迭代函数创建的行上下文如果不转化,都会被参数中的聚合函数忽略啊?
上下文这个好难理解,望老师帮忙解惑,谢谢!
老师,”在 TopDate 公式的第二种写法中,LASTNONBLANK 使用了一个常数 1 作为第二参数”. 这里实际上面用的是FIRSTNONBLANK,可能写错了。
老师,为什么这个按案例来,度量值结果返回的是杨戬(Y)不是楚杰(C)?
感谢老师之前的回复
以下是我今天的理解请老师看一看是否正确
F1 = FIRSTNONBLANK(‘Table'[地区经理],CALCULATE(SUM(‘Table'[销售额])))
白德伟成为最后一个的原因是,第二参数CALCULATE(SUM(‘Table'[销售额])在百德伟这一行的行上下文计值为空,所以百德伟被跳过,选择首字母为C的楚杰。
而F2 = FIRSTNONBLANK(‘Table'[地区经理],SUM(‘Table'[销售额]))
百德伟成为第一的原因是,第二参数SUM(‘Table'[销售额])忽略了百德伟这行的行上下文并且计值为销售额的总和,即使白德伟销售额为空也不影响他的排序,所以首字母为B排位最高的白德伟成为第一个。
我的理解是,先进行排序,再看第二参数在行上下文的作用下计值是否为空,如果本来排在首位的计值为空则被跳过,选第二个,第二个还是为空选第三个,以此类推。
F1 = FIRSTNONBLANK(‘Table'[地区经理],CALCULATE(SUM(‘Table'[销售额])))
这个表达式,第二个参数是不是等于没发挥作用?
为什么F2中“白德伟”变第一个了,所有销售额不应该都是一样的吗?
这个网站是知识含量最高的!
请问下,示例中,F1 = FIRSTNONBLANK(‘Table'[地区经理],CALCULATE(SUM(‘Table'[销售额])))返回的结果,为何不是最小记录:杨健?