彻底理解 PowerBI DAX 函数 EARLIER
共 4848字,需浏览 10分钟
·
2021-02-02 21:33
很多业务背景的伙伴进入 DAX 世界后,第一个拦路虎就是 EARLIER。
因为这是我们业务人员平时不用的思维逻辑:迭代。
迭代,是区分文科与理科;业务与 IT 的标志性思维逻辑。
迭代,在传统的编程领域又叫循环,迭代是循环的等价。
本文让您彻底理解 EARLIER 以及迭代,不管你是什么背景。
什么叫迭代
迭代,简单说就是数数;而精确说,就是:对已知集合中元素的遍历。
例如:我们有一个集合:{ 1, ... , 10 },对这个集合的遍历,就是挨个看一遍。
例如:我们有一个集合:{ 苹果,鸭梨,橘子,香蕉 },对这个集合的遍历,就是挨个看一遍。
从这个意义上来说,迭代本身是很傻的,光看不做事。
所以,伴随着着迭代,一般都得做点坏事,不然不白迭代了,白看了。
理解 DAX 中的 SUM
在 DAX 中,SUM 的用法如下:
[Sales] := SUM( Order[Amount] )
它完全等价于:
[Sales] := SUMX( Order , Order[Amount] )
其含义为:
对 Order 表进行迭代,并把遍历到的数据行的 [Amount] 列的值提取出来全部加起来。
从逻辑上来讲,SUMX 有两个重要动作:
在遍历的元素的时候提取元素
最后在遍历完成时全部加起来
注意:实际 DAX 引擎的物理执行可能与此不同,但逻辑上可以这么理解。
SUMX 中隐藏的迭代器
SUMX 的执行如下:
SUMX( Order , Order[Amount] ) =
【 迭代开始{ 】
row1 , 取出当前行 [Amount]
row2 , 取出当前行 [Amount]
row3 , 取出当前行 [Amount]
row4 ,取出当前行 [Amount]
...
【 } 迭代完成 】
【【将所有取出的值相加并返回。】】
其中:
【迭代开始{ ... } 迭代完成】为隐藏的内置迭代器
【【..】】为迭代完后的内置操作
由于这两步逻辑被 SUMX 隐藏了,很多业务背景的伙伴就不得理解:
到底迭代器长成啥样
迭代里面发生了啥
迭代完了发生了啥
以上图示为了更加形象地说明这个过程。
迭代中的行上下文
在 DAX 中,表可以是这样的:
{ 1 , 2 , 3 }
// 或者这么写
{
1,
2,
3
}
这会得到:
由于没有给这个表的列起名字,这一列默认叫 Value,那么来考察:
SUMX (
{
1,
2,
3
},
[Value]
)
可以得到:
在迭代中,可以从[Value]列取出值必须要能锁定当前的行,就是行上下文。
也就是说,在迭代中,遍历的每个元素就是行上下文,在行中可以取出列值,否则无法做到。
注意
很多初学者问:什么叫行上下文?其实更应该换一个问法。
一个更好的问题应该是:
在迭代一个集合的时候,DAX 是否有什么机制来让用户可以操作正在遍历的元素?
回答:
DAX 有这种机制,并起名叫:行上下文,用来取出迭代中正在遍历的元素。
这很好,正如我们的预期。
进入烧脑阶段开始。
多层迭代 - 同名覆盖
请考察:
SUMX (
{ 1, 3 },
SUMX ( { 1, 2 } , [Value] * [Value] )
)
对于 { 1 , 3 } 来说,它有一列叫:[Value];
对于 { 1 , 2 } 来说,它也有一列叫:[Value]。
注意
由于两个 SUMX 的出现,也就出现了两套嵌套的迭代器,这就形成了在 迭代 中的 迭代,也就是:多层迭代。
那么,此处的 [Value] * [Value] 到底指的是:谁的[Value] * 谁的[Value] 呢?
其执行细节如下:
[Value] [Value]
1
1 1 * 1
2 2 * 2
3
1 1 * 1
2 2 * 2
这里用 TAB 的缩进表示了不同的层次。
请仔细观察上述内容,理解其规律。可以知道:[Value] 指的是 { 1, 2 } ,这是合理和自然的。也就是说:
迭代 迭代
[Value] [Value]
1
1 当前行上下文[Value] 1 * 当前行上下文[Value] 1 = 1
2 当前行上下文[Value] 2 * 当前行上下文[Value] 2 = 4
3
1 当前行上下文[Value] 1 * 当前行上下文[Value] 1 = 1
2 当前行上下文[Value] 2 * 当前行上下文[Value] 2 = 4
是实际执行的逻辑结构。其结果如下:
不难发现,其结果是预期的,同时发现:
根本没有用到 { 1 , 3 } 以及其中的元素,在更复杂的场景中,业务上需要:在内层可以访问到外层同名的列。
多层迭代 - 内外跨层穿越
考察上面已经有的结构:
迭代 迭代
[Value] [Value]
1
1 当前行上下文[Value] 1 * 当前行上下文[Value] 1 = 1
2 当前行上下文[Value] 2 * 当前行上下文[Value] 2 = 4
3
1 当前行上下文[Value] 1 * 当前行上下文[Value] 1 = 1
2 当前行上下文[Value] 2 * 当前行上下文[Value] 2 = 4
如果我们希望这样呢:
迭代 迭代
[Value] [Value]
1
1 当前行上下文[Value] 1 * 上一层迭代的行上下文中的[Value] 1 = 1
2 当前行上下文[Value] 2 * 上一层迭代的行上下文中的[Value] 1 = 2
3
1 当前行上下文[Value] 1 * 上一层迭代的行上下文中的[Value] 3 = 3
2 当前行上下文[Value] 2 * 上一层迭代的行上下文中的[Value] 3 = 6
在 DAX 中就需要这样编写,如下:
可以看出:
EARLIER( C , X ) 的精确语义是:
上 X 层迭代的行上下文中的列 C 的值。
若 X = 1,可以忽略,将 EARLIER( [Value] , 1 ) 简写为 EARLIER( [Value] )。
那么,函数 EARLIER 就起到了跨层穿越的效果。
多层迭代 - 默认穿越
在理解上述内容后,来看一道测试题吧:
VAR A = SELECTCOLUMNS( { 1, 3 } , "A" , [Value] )
VAR B = SELECTCOLUMNS( { 1, 2 } , "B" , [Value] )
RETURN SUMX (
A,
// 这里需要放一句话
)
这里需要放一句话,请选择:
选项 1 - SUMX ( B , [B] * [A] ),且选项 2 语法错误
选项 2 - SUMX ( B , [B] * EARLIER( [A] ) ),且选项 1 语法错误
在不做实验的情况下,请选择 A 还是 B 呢?
如果选项 1 对,那么说明:[A] 的访问,由于无同名列的遮挡,不需要跨层,也不能跨层,所以不能用 EARLIER;
如果选项 2 对,那么说明:[A] 的访问,虽然无同名列的遮挡,由于不同层,必须要跨层,所以必须用 EARLIER。
而实际的结果是:
在这个场景中,SUMX ( B , [B] * [A] ) 与 SUMX ( B , [B] * EARLIER( [A] ) ) 完全一致。
结果如下:
以及:
也就是说,在这个场景下的 SUMX ( B , [B] * [A] ) ,如下:
迭代 迭代
[A] [B]
1
1 当前行上下文[B] 1 * 当前行上下文[A] 1 = 1
2 当前行上下文[B] 2 * 当前行上下文[A] 1 = 2
3
1 当前行上下文[B] 1 * 当前行上下文[A] 3 = 3
2 当前行上下文[B] 2 * 当前行上下文[A] 3 = 6
完全等价于这个场景下的 SUMX ( B , [B] * EARLIER( [A] ) ) ,如下:
迭代 迭代
[A] [B]
1
1 当前行上下文[B] 1 * 上一层迭代的行上下文中的[A] 1 = 1
2 当前行上下文[B] 2 * 上一层迭代的行上下文中的[A] 1 = 2
3
1 当前行上下文[B] 1 * 上一层迭代的行上下文中的[A] 3 = 3
2 当前行上下文[B] 2 * 上一层迭代的行上下文中的[A] 3 = 6
这让我们得到以下结论:
DAX 提供了迭代中需要访问当前元素的机制,叫做:行上下文。
迭代是可以嵌套的。
在嵌套的迭代中,内层可以访问外层。
若列不遮挡,也就是使用不同层的不同名列,则可以直接访问,也可以使用 EARLIER 显式指定要访问的相对第 X 外层。
若列有遮挡,也就是使用不同层的相同名列,则默认使用内层,这必须使用 EARLIER 显式指定要访问的相对第 X 外层。
不论是内层或者外层,都处于(或有自己)相应的行上下文。
总结
要理解 EARLIER 就要知道行上下文;
要理解 行上下文就要知道迭代;
迭代是遍历大量元素的逻辑手段;
在数据模型中,大量元素以逻辑行的形式存在于表中;
遍历表的元素,就是表的行;
从正在遍历(迭代)的行中取出值需要一个机制来框住当前行,称为:行上下文;
迭代是可以多层嵌套的;
从更内层迭代中的行上下文可以访问相对外层迭代中的行上下文,这时使用 EARLIER 即可。
EARLIER,顾名思义,更早的,意思为更早创建出的行上下文。
用 EARLIER 实现的这种牛叉特性可以起一个牛叉的名字:跨层穿越。
BI佐罗讲解的 DAX 是从本质层面进行的,本质不表示大而全,而是逻辑的完备和简洁,学习 EARLIER 竟不需要任何一个业务表,因为基本数学知识足以。学习《BI真经》,窥见更多本质。
让数据真正成为你的力量
Create value through simple and easy with fun by PowerBI
Excel BI | DAX Pro | DAX 权威指南 | 线下VIP学习
扫码与PBI精英一起学习,验证码:data2021
PowerBI MVP 带你正确而高效地学习 PowerBI
点击“阅读原文”,即刻开始
↙