DAX从入门到精通 4-3-1 使用earlier函数

使用earlier函数

你可能认为,在行上下文中对同个表格进行多次嵌套是非常少见的。实际上,这个情况经常发生。我们看下下面这个例子。设想你想计算,针对每个产品,有多少个其他的产品价格是高于该产品的。这个需要对产品的价格进行排序。
要解决这个问题,我们使用filter函数,这个函数我们之前使用过。回忆一下,filter使用迭代计算,对表的所有行进行计算,然后返回一个仅包含符合条件的行的表。例如,你要筛选大于100元的产品。可以这样写:

= FILTER ( Product, Product[UnitPrice] > 100 )

回到刚才那个案例:建立了计算列,然后计数所有单价大于当前行产品单价的产品。如果你称当前产品价格为 PriceOfCurrentProduct。那么我们可以很容易的写出我们需要的计算:

Product[UnitPriceRank] =
COUNTROWS (
FILTER (
Product,
Product[UnitPrice] > PriceOfCurrentProduct
))

filter返回了那些价格高于当前产品价格的记录,然后返回计数结果。剩下的问题就是如何表达当前的产品,用这个来代替PriceOfCurrentProduct。当前行,也就是DAX用于计算的行的金额,这个表达式的写法,比你设想的会难一些。
我们在Product表中定义了计算列,所以,DAX会创建一个行上下文来迭代。但是,表达式使用了filter函数在同一个表也创建了行上下文。事实上,在第五行使用的Product[UnitPrice]的值就是当前行的值。这个情况下,新的行上下文会隐藏旧的行上下文,所以说,你要使用的是当前单元格所在行的值而不是最后行上下文生成的值。也就是你要使用的是上一次的行上下文,也就是计算列生成的。
DAX提供了一个函数,使得整个需求变的可能:earlier。它可以提取之前一个行上下文生成的列的值,而不是最后的一个。所以,PriceOfCurrentProduct可以使用Earlier(product[unitprice])。
earlier是DAX中最奇特的一个函数,许多学生对Earlier感到陌生,因为没有从行上下文的角度思考,以及没有考虑导可以在同一个表格中,嵌套了两个行上下文。事实上,EARLIER是很简单函数,很多情况下都可以使用,下面整个代码可以解答我们的需求:

Product[UnitPriceRank] =
COUNTROWS (
FILTER (
Product,
Product[UnitPrice] > EARLIER ( Product[UnitPrice] )
))
+ 1

下图可以看到在Product表定义了计算列,使用了Unit Price作为关键字降序排列


image.png

因为有14个产品的价格一样,所以它们的排名都是1,第15个产品的排序是15,同价格的产品排名也是15。我们强烈的建议你认真的学习这个小的案例,因为它能很好的检测你对行上下文的理解和使用,如何使用filter建立,以及使用earlier获取之前的行上下文结果。

笔记
earlier可以接受第二个参数,用来代表要跳过多少次之前的上下文,所以你可以跳过2次或者3次。另外,还有个earliest可以使你直接获取导最外层的行上下文。但是,通常情况下,earlier和earliest的第二个参数都是极少用到的。因为嵌套两次行上下文的情景非常常见,但是3次及以上的情况就非常少遇到了。

在结束这个案例之前,还可以再说点,例如你想把值的排序转成另外一种排序的方式,按价格而不是按产品。这里,我们可以使用values函数,之前章节我们有学过。

Product[UnitPriceRankDense] =
COUNTROWS (
FILTER (
VALUES ( Product[UnitPrice] ),
Product[UnitPrice] > EARLIER ( Product[UnitPrice] )
))
+ 1

我们可以看看新创建的计算列


image.png

我们强烈的建议你认真的把earlier函数学习一遍,因为它非常的常用。不过,作为替代方案,我们还可以使用变量。使用变量可以是代码更容易阅读。例如,之前的需求可以用这个表达式来书写:

Product[UnitPriceRankDense] =
VAR
CurrentPrice = Product[UnitPrice]
RETURN
COUNTROWS (
FILTER (
VALUES ( Product[UnitPrice] ),
Product[UnitPrice] > CurrentPrice
))
+ 1

这个代码中,我们使用了变量,我们把当前的价格存储再了CurrentPrice变量中,然后在后面的对比中使用它。给变量一个名称可以使得代码更容易阅读,而不是每次阅读的代码的时候,都要在一堆的代码中重新检查代码的逻辑。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容