1. 程式人生 > 實用技巧 >Power BI 瞭解DAX中LASTDATE和MAX之間的區別

Power BI 瞭解DAX中LASTDATE和MAX之間的區別

許多剛開始使用DAX的小夥伴在使用LASTDATE搜尋某個時間段內的最後日期。或者他們使用NEXTDAY檢索給定日期之後的日期。儘管這些函式可以實現它們所承諾的功能,但它們並不打算在簡單的表示式中使用。相反,它們是設計用於時間智慧計算的表函式。錯誤地使用它們會導致程式碼效率低下。此外,以未設計的方式使用這些功能是一個明顯的訊號,表明開發人員仍未掌握DAX的某些細節。

在本文中,我們將詳細介紹該主題,以便了解這些時間智慧功能的作用。我們還想了解在日期上將它們與簡單的數學混淆如此容易的原因。我們想通過例子來詳細闡述這個話題。因此,我們從無聊的理論開始,而不是從一個計算開始,儘管這種計算工作得很好,但它本質上是錯誤的。

計算給定選擇中包含的天數,並生成如下所示的報告。

計算DaysInPeriod很簡單:天數是時間段中第一個日期和最後一個日期之間的差。DAX提供了兩個功能:FIRSTDATELASTDATE,這似乎是完美的候選者:

Days in period :=
INT ( LASTDATE ( 'Date'[Date] ) - FIRSTDATE ( 'Date'[Date] ) )

這項措施可以正常工作併產生正確的結果。因此,我們很高興!對?錯誤。我們不滿意,因為我們使用LASTDATE來檢索一個時間段內最後一個可見日期的值。LASTDATE完全執行此作業,但它返回一個包含最後日期的表-不僅是日期。

讓我重複一遍:它不返回日期。它返回一個包含日期的表。

這樣做的原因是LASTDATE是時間智慧功能。其主要目的是用作CALCULATE中的過濾器引數CALCULATE過濾器引數是表。因此,要使函式在以下度量中使用,它需要返回一個表:

SalesOfLastDay =
CALCULATE (
    [Sales Amount],
    LASTDATE ( 'Date'[Date] )
)

您可以使用DAX Studio再次檢查LASTDATE的結果LASTDATE返回一個表。這就是為什麼您可以在EVALUATE語句中使用它的原因,該語句需要一個表作為結果。

如您所見,結果是一個表,其中包含一列(

Date)和最後一個日期的值。

在DAX中,可以使用僅包含一行和一列的表(即您從LASTDATE獲得的結果)代替內部的值。實際上,單行一列的表僅包含一個值。這就是DAX允許您將表自動轉換為值的原因。這也是您可以在我們的度量中減去兩個表的原因:

Days in period :=
INT ( LASTDATE ( 'Date'[Date] ) - FIRSTDATE ( 'Date'[Date] ) )

實際上,LASTDATEFIRSTDATE都返回表。因為我們使用的是減法運算子,所以DAX會將兩個錶轉換為標量值,然後計算表內包含的值之間的差。

儘管此行為是透明的,但它是有代價的。表示先前計算的一種更好的方法是使用標量函式,例如MIN而不是FIRSTDATEMAX而不是LASTDATEMINMAX不返回表:它們返回第一個和最後一個日期的值。因此,以下是對措施的更好表述:

Days in period MIN MAX :=
INT ( MAX ( 'Date'[Date] ) - MIN ( 'Date'[Date] ) )

同樣,您可以使用DAX Studio再次檢查MINMAX的結果如果您嘗試使用MAX而不是LASTDATE作為EVALUATE語句的結果,則會出現錯誤。

為了獲得EVALUATE的結果,您需要構建一個包含最大日期的表。例如,您可以使用表建構函式執行此操作。

如前所述,DAX自動將具有一行和一列的錶轉換為值。但是這種行為是有代價的。此外,LASTDATEFIRSTDATE都在查詢第一個和最後一個日期之前執行上下文轉換。此行為不會影響我們的簡單示例,但是僅由於此方面,在更復雜的情況下效能可能會很差。

本文是DAX 101;因此,它應該在這裡結束。但是,當然,我們不禁為您中最好奇的人提供更多詳細資訊。您如何檢查公式的兩個版本之間的行為差​​異?

通過使用DAX Studio,您可以分析此查詢的伺服器時間:

--
--    This version uses FIRSTDATE and LASTDATE
--
EVALUATE
SUMMARIZECOLUMNS (
    'Date'[Year Month],
    "Days in period", [Days in period]
)

儘管速度非常快,但是可以從伺服器計時中看到引擎必須兩次實現Date表:一次用於Date [Date]列,一次用於兩列Date [Date]Date [Calendar Year Month],生成兩個具有2,556行的資料快取。公式引擎(FE)隨後掃描這些資料快取以計算所需的結果。

通過這種簡單的計算,當查詢使用優化版本MINMAX內的天數時,查詢不會更快仍然,在實現方面要好得多,因為將整個計算下推到儲存引擎(SE),該引擎將生成具有87行的單個數據快取:與查詢結果相同的行數。因此,期間MINMAX中天數將通過SE執行的完整計算產生最佳實現。在較大的模型或更復雜的場景中,實現上的這種微小差異可能會產生巨大的影響。

請注意,大多數時間智慧功能(例如FIRSTDATELASTDATENEXTDAYPREVIOUSDAY…)都顯示相同的行為:它們返回一個可以自動轉換為標量值的表。但是轉換的代價是不值得付出的。

瞭解函式的一些本質也是變相的改善報告的效能,就也是為什麼我在之前的文章中一再強調某些函式是如何運算,可能很多小夥伴只注重結果正確而忽略了一些細節。