1. 程式人生 > >DAX 獲取前N個數值

DAX 獲取前N個數值

在資料報表中常有一類需求是按照一定要求對資料進行排序,然後根據排序結果,獲取前N個數據,例如,求總成績排名前10的學生,求銷售量最多的前3個產品等等。

在DAX中要實現該需求,通常是用的函式有兩個,一個是TOPN,還有一個是RANKX。本文主要介紹TOPN的用法,其語法結構如下:

TOPN(<n_value>, <table>, <orderBy_expression>, [<order>[, <orderBy_expression>, [<order>]]…])

TOPN函式主要有3個引數組成:

  • <n_value>處需要填寫一個返回的行數,也就是想要獲取前多少個數據,即N值。可以是一個數字,也可以是一個返回單一數字的表示式。
  • < table>處指定從哪個表單中獲取前N個數據,可以填寫一個表單或者可以返回表單的表示式。
  • <orderBy_expression>處填寫一個表示式,該表示式的返回結果將作為表單的排序依據。
  • < order>是一個可選項,如果填寫0或者FALSE或者DESC,代表按照降序對錶單進行排序;如果填寫1或者TRUE或者ASC,則按照升序對錶單進行排序。如果預設則表示0,如果填寫其他數值,則DAX會報錯。

TOPN函式的返回結果是一個表單,也就是說,如果是單一的直接使用TOPN函式,只能通過建立一個計算表單來呼叫。如果是想在度量值或則計算列中使用TOPN函式,則必須作為其他函式的引數而進行使用。

說明:

  1. n_value這個地方如果填寫的是正小數,則DAX會取小數點後一位,然後按照四捨五入規則轉換成整數,來確定N值。 如果填寫的是負數或者0,則返回空表單。
  2. 對於排序結果,如果有相同值,即排序序號相同,當這種資料符合前N的篩選條件時,TOPN函式會把相同值資料都作為結果進行返回。
  3. TOPN的輸出結果屬於無序排序,也就是說雖然會返回前N行資料,但是第一行中的排序列下資料可能並不是最大/最小值。

TOPN函式最常見的的應用場景是求前N個數據的總和,例如,求下圖銷售量前3的商品總和,就可以建立一個度量值利用SUMX函式和TOPN函式來進行。

TopN_Q_SUM =
SUMX (
    TOPN ( 3, SalesInfo, SalesInfo[Sales Volume], 0 ),
    SalesInfo[Sales Volume]
)

在這裡插入圖片描述

公式裡面用了最基本常規的演算法,可以看得TOPN函式按照原始表單的Sales Volume值對資料進行了排序,然後將數值最大的前三行資料組成一個表單返回給外圍SUMX函式使用。 可以通過下面這個計算表更加清晰獲得TOPN函式的計算結果。 在這裡插入圖片描述 之所以要強調TOPN返回的表單結果是因為如果用TopN_Q_SUM這個度量值去建立表單,會造成一種錯覺,以為獲取的前N個數值有問題。如下圖,Total處的統計值顯示2000,按照理解應該是銷售排名前三的銷售量總和,但是單從這個表單看,前三產品的銷售額分別是1000, 900,和700,其和並不等於2000。 在這裡插入圖片描述 之所以出現這個原因是因為在當前計算表中,TopN_Q_SUM的計算會受到Product這個篩選上下文的影響,例如當Product = Computers的時候,實際上是將原始表單進行了過濾,只保留了 Product = Computers的子表單,之後TOPN對改子表單中的Sales Volume進行了排序,獲取了前3個最大值,之後經過SUMX進行了求和計算。 在這裡插入圖片描述

由於TopN_Q_SUM的計算公式中表單引數直接填寫的是當前SalesInfo表單,所以每次資料的計算都是依據被篩選上下文影響的整個SalesInfo表單來進行。

如果不按照Country列對Product進行分類,只是單純的對每種產品銷售量前3的資料進行彙總求和,則需要對TopN_Q_SUM函式進行修改,利用SUMMARIZE函式,將TOPN函式中的引數表單變成按照Product彙總過後的資料表,之後再進行計算即可。

TopN_Q_SUM =
SUMX (
    TOPN (
        3,
        SUMMARIZE (
            SalesInfo,
            SalesInfo[Product],
            "Volume", SUM ( SalesInfo[Sales Volume] )
        ),
        [Volume], 0
    ),
    [Volume]
)

在這裡插入圖片描述