DAX 第七篇:分組聚合

DAX有三個用於生成分組聚合數據的函數,這三個函數有兩個共同的特徵:分組列和擴展列。express

  • 分組列是用於分組的列,只能來源於基礎表中已存的列,分組列能夠來源於同一個表,也能夠來源於相關的列。
  • 擴展列是由name和expression對構成的,name是字符串,expression是包含聚合函數的表達式。

在分組列和擴展列上,這三個函數有各自獨特的處理方式。函數

一,SUMMARIZE

SUMMARIZE函數對相互關聯的Table按照特定的一個字段(分組列)或多個字段,進行分組聚合。因爲分組列是惟一的,經過SUMMARIZE函數,能夠得到多列的惟一值構成的二維表:spa

SUMMARIZE(<table>, <groupBy_columnName>[, <groupBy_columnName>]…[, <name>, <expression>]…)

參數註釋:excel

  • table:必需參數,表示主表,能夠是任何返回表的表達式。
  • groupBy_columnName:可選參數,表示分組列,該列必須是table參數中的列,或者相關聯表中的列。分組列必須使用列的徹底限定名,格式是table[column],分組列能夠有0個,1個或多個。
  • name、expression:可選參數,表示自定義的彙總列/擴展列,該參數對老是成對出現的,name是expression計算結果的名稱,expression用於計算列的聚合值。

該函數的返回值是一個彙總表,彙總表包含分組列和自定義的擴展列。code

1,得到多列的惟一值blog

分組列是惟一的,能夠不返回彙總列,而只返回分組列,這樣獲得的表是多列的惟一值。ci

SUMMARIZE(ResellerSales , DateTime[CalendarYear] , ProductCategory[ProductCategoryName] ) 

2,得到彙總數據文檔

例如,對數據表 ResellerSales ,按照字段 DateTime[CalendarYear] 和 ProductCategory[ProductCategoryName]分組,計算 ResellerSales[SalesAmount]和 ResellerSales[DiscountAmount]的加和 。字符串

SUMMARIZE(ResellerSales , DateTime[CalendarYear] , ProductCategory[ProductCategoryName] , "Sales Amount", SUM(ResellerSales[SalesAmount]) , "Discount Amount", SUM(ResellerSales[DiscountAmount]) ) 

該函數利用ResellerSales和DateTime、ProductCategory之間的關係,獲得關聯表數據(是一箇中間臨時表),按照DateTime[CalendarYear] 和 ProductCategory[ProductCategoryName]  對關聯以後的數據進行分組,分別計算銷售和折扣的加和。get

注意,ResellerSales和DateTime,ResellerSales和ProductCategory 必須顯式存在關係,不然,不能用於分組列中。

3,分組聚合的做用

第一是做爲中間臨時表,爲後續的計算提供數據;第二是用於建立新表,在Modeling菜單中,經過「New Table」從DAX表達式中建立新的Table:

參考文檔:SUMMARIZE – groupping in data models (DAX – Power Pivot, Power BI)

4,ROLLUP選項

ROLLUP函數用於對分組列進行上卷操做,該函數用於預約義多個分組集:

SUMMARIZE(<table>, <groupBy_columnName>[, <groupBy_columnName>]…[, ROLLUP(<groupBy_columnName>[,< groupBy_columnName>…])][, <name>, <expression>]…)

做用相似於TSQL的 rollup函數,例如,對於group by rollup(a,b) ,其表示的分組集是group by (), group by (a), group by (a,b)。

5,ROLLUPGROUP選項

ROLLUPGROUP函數用於計算小計組。若是把ROLLUPGROUP來代替ROLLUP函數,那麼ROLLUPGROUP經過向groupBy_columnName列的結果添加彙總行來產生和ROLLUP相同的結果。 可是,在ROLLUP語法中添加ROLLUPGROUP()可用於防止彙總行中的部分小計。例如,ROLLUP(ROLLUPGROUP(A,B)),分組集是(A,B)和():

SUMMARIZE(ResellerSales_USD , ROLLUP(ROLLUPGROUP( DateTime[CalendarYear], ProductCategory[ProductCategoryName])) , "Sales Amount (USD)", SUM(ResellerSales_USD[SalesAmount_USD]) , "Discount Amount (USD)", SUM(ResellerSales_USD[DiscountAmount]) ) 

6,ISSUBTOTAL選項

只能用於SUMMRIZE函數中,用於檢查該列是否爲小計組。

SUMMARIZE(<table>, <groupBy_columnName>[, <groupBy_columnName>]…[, ROLLUP(<groupBy_columnName>[,< groupBy_columnName>…])][, <name>, {<expression>|ISSUBTOTAL(<columnName>)}]…)

例如,使用該函數檢查CalendarYear和 ProductCategoryName是否爲小計組:

SUMMARIZE(ResellerSales_USD , ROLLUP( DateTime[CalendarYear], ProductCategory[ProductCategoryName]) , "Sales Amount (USD)", SUM(ResellerSales_USD[SalesAmount_USD]) , "Discount Amount (USD)", SUM(ResellerSales_USD[DiscountAmount]) , "Is Sub Total for DateTimeCalendarYear", ISSUBTOTAL(DateTime[CalendarYear]) , "Is Sub Total for ProductCategoryName", ISSUBTOTAL(ProductCategory[ProductCategoryName]) )

二,SUMMARIZECOLUMNS

該函數也用於分組聚合,和SUMMARIZE函數的差別在於分組列之間的關係是非必需的,分組列之間執行的交叉鏈接或自動存在。

SUMMARIZECOLUMNS( <groupBy_columnName> [, < groupBy_columnName >]…, [<filterTable>]…[, <name>, <expression>]…)

參數註釋:

  • groupBy_columnName:分組列,該列必須使用列的徹底限定名,格式是base_table[column],該列必須是基礎表中的現存列,分組列能夠有0個,1個或多個。多個分組列之間的表不要求必須有關係,對於不一樣表,分組列之間是交叉鏈接(cross-join);對於相同表,分組列之間使用的是自動存在(auto-existed)。
  • filterTable:可選參數,對分組列所在的基礎表進行過濾, 過濾器表中存在的值用於在執行交叉鏈接/自動存在以前進行過濾。
  • name、expression:可選參數,表示自定義的彙總列,該參數對老是成對出現的,name是expression計算結果的名稱,expression用於計算列的聚合值。

返回值是彙總表,包含分組列和自定義列,返回的數據行中,至少包含一個非空值,若是在一個數據行中,全部expression的結果都是BLANK/NULL,那麼該行不包含在彙總表中。

1,分組字段進行笛卡爾乘積

如下DAX按照SalesTerritory的字段Category 和 Customer的Education字段進行分組,並對Customer表進行過濾:

SUMMARIZECOLUMNS ( 'SalesTerritory'[Category], 'Customer' [Education], FILTER('Customer', 'Customer'[First Name] = 「Alicia」) )

對過濾以後的數據進行彙總計算,返回的結果是Category和Eduction的笛卡爾乘積。

2,IGNORE選項

把包含NULL/BLANK的行過濾掉

SUMMARIZECOLUMNS(<groupBy_columnName>[, < groupBy_columnName >]…, [<filterTable>]…[, <name>, IGNORE(…)]…)

例如,若是Sum(Sales[Qty] )中包含一個NULL/BLANK,那麼把該行從結果集中移除:

SUMMARIZECOLUMNS( Sales[CustomerId], "Total Qty", IGNORE( SUM( Sales[Qty] ) ), 「BlankIfTotalQtyIsNot3」, IF( SUM( Sales[Qty] )=3, 3 ) )

3,其餘選項

  • NONVISUAL()
  • ROLLUPADDISSUBTOTAL()
  • ROLLUPGROUP()

三,GROUPBY

GROUPBY函數除了不能再擴展列中使用CALCULATE函數以外,和SUMMARIZE的用法相同:

GROUPBY (<table>, [<groupBy_columnName1>]..., [<name>, <expression>]… )

expression參數中不能使用CALCULATE函數,CURRENTGROUP 函數只能用於最頂層的表掃描(Table Scan)操做。

GROUPBY函數執行的操做是:

  • #1:從指定的表(以及「to-one」方向的全部相關表)開始
  • #2:按照全部的GroupBy列建立分組,每個分組表明一組數據行
  • #3:對於每個分組,評估要增長的擴展列(Extension column)。與SUMMARIZE函數不一樣,不執行隱含的CALCULATE,而且不把該組放入到過濾器上下文中。

在該函數中,能夠調用CURRENTGROUP 函數:

CURRENTGROUP()

該函數只能用於GROUPBY函數的expression參數中,表示當前分組。 CURRENTGROUP函數不帶參數,僅支持做爲如下聚合函數之一的第一個參數:AverageX,CountAX,CountX,GeoMeanX,MaxX,MinX,ProductX,StDevX.S,StDevX.P,SumX,VarX.S,VarX.P。舉個例子,對Sales表,按照Country和Category進行分組,計算每一個分組中Price * Qty的乘積之和。

GROUPBY ( Sales, Geography[Country], Product[Category], 「Total Sales」, SUMX( CURRENTGROUP(), Sales[Price] * Sales[Qty]) )

 

參考文檔:

SUMMARIZE

SUMMARIZECOLUMNS

GROUPBY

DAX function reference

相關文章
相關標籤/搜索