DAX從入門到精通 4-3-1 使用earlier函數

使用earlier函數

你可能認為,在行上下文中對同個表格進行多次嵌套是非常少見的。實際上,這個情況經常發(fā)生。我們看下下面這個例子。設想你想計算,針對每個產品,有多少個其他的產品價格是高于該產品的。這個需要對產品的價格進行排序。
要解決這個問題,我們使用filter函數,這個函數我們之前使用過?;貞浺幌?,filter使用迭代計算,對表的所有行進行計算,然后返回一個僅包含符合條件的行的表。例如,你要篩選大于100元的產品??梢赃@樣寫:

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

回到剛才那個案例:建立了計算列,然后計數所有單價大于當前行產品單價的產品。如果你稱當前產品價格為 PriceOfCurrentProduct。那么我們可以很容易的寫出我們需要的計算:

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

filter返回了那些價格高于當前產品價格的記錄,然后返回計數結果。剩下的問題就是如何表達當前的產品,用這個來代替PriceOfCurrentProduct。當前行,也就是DAX用于計算的行的金額,這個表達式的寫法,比你設想的會難一些。
我們在Product表中定義了計算列,所以,DAX會創(chuàng)建一個行上下文來迭代。但是,表達式使用了filter函數在同一個表也創(chuàng)建了行上下文。事實上,在第五行使用的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函數,之前章節(jié)我們有學過。

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

我們可以看看新創(chuàng)建的計算列


image.png

我們強烈的建議你認真的把earlier函數學習一遍,因為它非常的常用。不過,作為替代方案,我們還可以使用變量。使用變量可以是代碼更容易閱讀。例如,之前的需求可以用這個表達式來書寫:

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

這個代碼中,我們使用了變量,我們把當前的價格存儲再了CurrentPrice變量中,然后在后面的對比中使用它。給變量一個名稱可以使得代碼更容易閱讀,而不是每次閱讀的代碼的時候,都要在一堆的代碼中重新檢查代碼的邏輯。

?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容