本文講解DAX函數SUMMARIZECOLUMNS基本的原理與用法
前述
國内外關于DAX函數的講解已很多,但個别函數還是有必要拿出來再講講。本文結合MarcoRusso關于SUMMARIZECOLUMNS函數的理論以及自身對其的研究,專門講解該函數,并分為多個篇章。本篇将講解其基本原理與用法。
文法
首先是函數的文法:
SUMMARIZECOLUMNS(
<groupBy_columnName>
[, < groupBy_columnName >]…
, [<filterTable>]…[, <name>, <expression>]…
)
其參數定義如下表所示:
參數 | 必要 | 可重複 | 描述 |
---|---|---|---|
groupBy_ColumnName | ✓ | ✓ | 用于分組的列 |
filterTable | × | ✓ | 提供篩選上下文的表或表表達式 |
name | × | ✓ | 添加的新列名稱 |
expression | × | ✓ | 新列的表達式 |
基本原理與用法
先講一個此函數的典型特征:SUMMARIZECOLUMNS隻有篩選上下文,沒有行上下文。比如對于如下資料模型:
使用DAX建立表如下:
SUMMARIZECOL_NONMEASURE =
SUMMARIZECOLUMNS (
'DimProductCategory'[ProductCategoryName],
'DimDate'[FiscalMonth]
)
它将根據這兩列,單純地CROSSJOIN成一個笛卡兒積表,也就是兩個字段值所有可能的組合,如下:
這就是因為SUMMARIZECOLUMNS本身并未指定主表,兩個來自不同表的字段不能産生任何關聯,而函數引擎也無法為其生成對應的行上下文。
一旦在函數中引入可選參數filterTable,并指定主表,公式就可以傳回資料集中真實存在的非空組合,而非笛卡兒積, 這就是因為SUMMARIZECOLUMNS利用了’FactSales’的行上下文對結果集進行了篩選。
SUMMARIZECOL_NONMEASURE =
SUMMARIZECOLUMNS (
'DimProductCategory'[ProductCategoryName],
'DimDate'[FiscalMonth],
'FactSales'
)
如果引入路徑成本,SUMMARIZECOLUMNS也可以借用路徑成本所在表的行上下文對其産生的結果集進行篩選。此外,如果所有的路徑成本對某一行的計算結果為空,該行将會被排除。
此處,我們引入路徑成本。DAX建立表如下:
SUMMARIZECOL =
SUMMARIZECOLUMNS (
'DimProductCategory'[ProductCategoryName],
'DimDate'[FiscalMonth],
"SALES", SUM ( 'FactSales'[SalesQuantity] )
)
可得到:
這裡公式傳回結果的原理為:SUMMARIZECOLUMNS借用了主表的行上下文,對SALES值進行求和計算,并使用[ProductCategoryName]以及[FiscalMonth]對結果進行GroupBy,并過濾SALES為空的行。
如果我們使用SUNMARIZE函數來模拟以上SUMMARIZECOLUMNS的計算,則公式為:
SUMMARIZECOL_SIMULATE =
FILTER (
SUMMARIZE (
CROSSJOIN (
VALUES ( 'DimProductCategory'[ProductCategoryName] ),
VALUES ( 'DimDate'[FiscalMonth] )
),
'DimProductCategory'[ProductCategoryName],
'DimDate'[FiscalMonth],
"SALES", CALCULATE ( SUM ( 'FactSales'[SalesQuantity] ) )
),
NOT ISBLANK ( [SALES] )
)
該公式将傳回與上圖相同的結果。注意,此公式僅僅是為了便于讀者了解其原理,實際使用時,還是推薦你直接使用SUMMARIZECOLUMNS,因為前者執行了三個SE查詢,效率低于後者。
有關SUMMARIZECOLUMNS相對于SUMMARIZE的性能優勢解析,可參見下篇部落格。