1. 程式人生 > 實用技巧 >Power BI Calculation Group

Power BI Calculation Group

優點

計算組解決了複雜模型中的問題,在這種模型中,可以使用相同的計算(最常見的時間智慧計算)來增加冗餘度量值。例如,銷售分析人員想要按月份截止日期(MTD)、季度截止到現在(QTD)、年初至今(YTD)、本年迄今訂單(PY)等來檢視銷售總額和訂單,等等。資料建模器必須為每個計算建立單獨的度量值,這可能會導致多個度量值。對於使用者而言,這可能意味著必須按多個度量值進行排序,並將它們分別應用到報表中。

首先,讓我們看一下如何在 Power BI 的報表工具中向用戶顯示計算組。接下來,我們將介紹如何組成計算組,以及如何在模型中建立計算組。

計算組在報告客戶端中作為具有單個列的表顯示。列不像典型的列或維度,而是表示一個或多個可重複使用的計算,或可應用於已新增到視覺化效果的值篩選器的任何度量值的計算項

在下面的動畫中,使用者正在分析銷售資料2012年和2013年。在應用計算組之前,通用基礎度量值銷售額計算每月總銷售額的總和。然後,使用者希望應用時間智慧計算,以獲取本月至今、季度截止到目前、本年迄今等的銷售總額。如果沒有計算組,則使用者必須選擇單個時間智慧度量值。

對於計算組,在此示例中,在名為Time 情報的情況下,當用戶將時間計算項拖到 "列" 篩選區域時,每個計算項都顯示為一個單獨的列。每行的值都是從基本度量值Sales計算得出的。

計算組使用顯式DAX 度量值。在此示例中,Sales是已在模型中建立的顯式度量值。計算組不能與隱式 DAX 度量值一起使用。例如,在 Power BI 隱式度量值是在使用者將列拖動到視覺物件上以檢視聚合值時建立的,而無需建立顯式度量值。目前,Power BI 為作為內聯 DAX 計算編寫的隱式度量值生成 DAX-這意味著隱式度量值不能與計算組一起使用。已在表格物件模型(TOM)中看到一個新的模型屬性,DiscourageImplicitMeasures。目前,若要建立計算組,必須將此屬性設定為true。如果設定為 true,則在 "實時連線" 模式下 Power BI Desktop 將禁用隱式度量值的建立。

計算組還支援多維資料表示式(MDX)查詢。這意味著,通過使用 MDX 查詢表格資料模型的 Microsoft Excel 使用者可充分利用工作表資料透視表和圖表中的計算組。

工作原理

現在,你已瞭解計算組如何使使用者受益,接下來讓我們看看如何建立顯示的 "時間智慧計算組" 示例。

在深入瞭解詳細資訊之前,讓我們先介紹一些用於計算組的新 DAX 函式:

SELECTEDMEASURE-用於計算項以引用當前上下文中的度量值的表示式。在此示例中,為 "銷售額" 度量值。

SELECTEDMEASURENAME-用於計算項的表示式,用來確定上下文中按名稱的度量值。

ISSELECTEDMEASURE-用於計算項的表示式,用來確定在度量值列表中指定的度量值。

SELECTEDMEASUREFORMATSTRING-用於計算項的表示式,用來檢索位於上下文中的度量值的格式字串。

時間智慧示例

表名-時間智慧
列名-時間計算
優先順序-20

時間智慧計算項

當前

DAX
SELECTEDMEASURE()

MTD

DAX
CALCULATE(SELECTEDMEASURE(), DATESMTD(DimDate[Date]))

QTD

DAX
CALCULATE(SELECTEDMEASURE(), DATESQTD(DimDate[Date]))

累計

DAX
CALCULATE(SELECTEDMEASURE(), DATESYTD(DimDate[Date]))

PY

DAX
CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR(DimDate[Date]))

PY MTD

DAX
CALCULATE(
    SELECTEDMEASURE(),
    SAMEPERIODLASTYEAR(DimDate[Date]),
    'Time Intelligence'[Time Calculation] = "MTD"
)

PY QTD

DAX
CALCULATE(
    SELECTEDMEASURE(),
    SAMEPERIODLASTYEAR(DimDate[Date]),
    'Time Intelligence'[Time Calculation] = "QTD"
)

PY YTD

DAX
CALCULATE(
    SELECTEDMEASURE(),
    SAMEPERIODLASTYEAR(DimDate[Date]),
    'Time Intelligence'[Time Calculation] = "YTD"
)

同比變化率

DAX
SELECTEDMEASURE() –
CALCULATE(
    SELECTEDMEASURE(),
    'Time Intelligence'[Time Calculation] = "PY"
)

同比變化率

DAX
DIVIDE(
    CALCULATE(
        SELECTEDMEASURE(),
        'Time Intelligence'[Time Calculation]="YOY"
    ),
    CALCULATE(
        SELECTEDMEASURE(),
        'Time Intelligence'[Time Calculation]="PY"
    ),
)

若要測試此計算組,請在 SSMS 或開源DAX Studio中執行 DAX 查詢。注意:此查詢示例中省略了同比變化率和同比變化率%。

時間智慧查詢

DAX
EVALUATE
CALCULATETABLE (
    SUMMARIZECOLUMNS (
        DimDate[CalendarYear],
        DimDate[EnglishMonthName],
        "Current", CALCULATE ( [Sales], 'Time Intelligence'[Time Calculation] = "Current" ),
        "QTD",     CALCULATE ( [Sales], 'Time Intelligence'[Time Calculation] = "QTD" ),
        "YTD",     CALCULATE ( [Sales], 'Time Intelligence'[Time Calculation] = "YTD" ),
        "PY",      CALCULATE ( [Sales], 'Time Intelligence'[Time Calculation] = "PY" ),
        "PY QTD",  CALCULATE ( [Sales], 'Time Intelligence'[Time Calculation] = "PY QTD" ),
        "PY YTD",  CALCULATE ( [Sales], 'Time Intelligence'[Time Calculation] = "PY YTD" )
    ),
    DimDate[CalendarYear] IN { 2012, 2013 }
)

時間智慧查詢返回

返回表顯示應用的每個計算項的計算。例如,請參閱3月2012日的 QTD 是二月份和三月2012之和。

動態格式字串

帶有計算組的動態格式字串允許將格式字串的條件應用應用於度量值,而無需強制它們返回字串。

表格模型通過使用 DAX 的FORMAT函式支援度量值的動態格式設定。但是,FORMAT 函式的缺點是返回一個字串,並強制執行其他為數字的度量值,並將其作為字串返回。這可能會有一些限制,例如不能使用大多數 Power BI 視覺物件,具體取決於數值,如圖表。

適用於時間智慧的動態格式字串

如果我們看一下上面所示的時間智慧示例,則除同比變化率%之外的所有計算項應在上下文中使用當前度量值的格式。例如,在銷售基準度量值上計算的YTD應為貨幣。如果這是一個計算組,而這種計算組類似於 Orders 基本度量值,則格式將為數值。不過,同比變化率%應為百分比,而不考慮基礎度量值的格式。

對於同比變化率%,我們可以通過將格式字串表示式屬性設定為0.00%;-0.00%; 0.00%,來覆蓋格式字串。若要詳細瞭解格式字串表示式屬性,請參閱MDX 單元屬性-格式字串內容。

在 Power BI 中的此矩陣視覺物件中,你會看到Sales current/同比變化率和ORDERS 當前/同比變化率保留各自的基本度量值格式字串。不過,SALES 同比變化率%和Orders 同比變化率%將覆蓋格式字串以使用百分比格式。

用於貨幣換算的動態格式字串

動態格式字串提供了簡單的貨幣換算。請考慮以下艾德作品資料模型。它針對轉換型別定義的一對多貨幣換算建模。

"格式字串" 列將新增到DimCurrency表中,並使用各自貨幣的格式字串填充。

在此示例中,將以下計算組定義為:

貨幣換算示例

表名稱-貨幣換算
列名稱-轉換計算
優先順序-5

用於貨幣換算的計算項

無轉換

DAX
SELECTEDMEASURE()

轉換貨幣

DAX
IF(
    //Check one currency in context & not US Dollar, which is the pivot currency:
    SELECTEDVALUE( DimCurrency[CurrencyName], "US Dollar" ) = "US Dollar",
    SELECTEDMEASURE(),
    SUMX(
        VALUES(DimDate[Date]),
        CALCULATE( DIVIDE( SELECTEDMEASURE(), MAX(FactCurrencyRate[EndOfDayRate]) ) )
    )
)

格式字串表示式

DAX
SELECTEDVALUE(
    DimCurrency[FormatString],
    SELECTEDMEASUREFORMATSTRING()
)

格式字串表示式必須返回標量字串。如果篩選器上下文中有多個貨幣,則使用新的SELECTEDMEASUREFORMATSTRING函式恢復為基本度量值格式字串。

以下動畫顯示了報表中銷售度量值的動態格式貨幣轉換。

優先順序

優先順序是為計算組定義的屬性。它指定了多個計算組時的計算順序。數字越大,表示優先順序越高,這意味著在優先順序較低的計算組之前計算。

在此示例中,我們將使用與上述時間智慧示例相同的模型,同時新增平均計算組。平均計算組包含與傳統時間智慧無關的平均計算,因為它們不會更改日期篩選器上下文,它們只會在其中應用平均計算。

在此示例中,將定義每日平均計算。對於石油和天然氣應用程式而言,一般的計算(例如每日的 barrels)都很常見。其他常見業務示例包含零售的商店銷售平均值。

雖然這種計算是獨立於時間智慧計算計算的,但也有可能需要將它們組合在一起。例如,使用者可能想要檢視 YTD 的 barrels,以檢視從該年開始到當前日期的每日燃油費率。在此方案中,應為計算項設定優先順序。

平均示例

表名稱為平均值。
列名為平均計算。
優先順序為10。

計算平均值的項

無平均值

DAX
SELECTEDMEASURE()

每日平均

DAX
DIVIDE(SELECTEDMEASURE(), COUNTROWS(DimDate))

下面是 DAX 查詢和返回表的示例:

平均查詢

DAX
EVALUATE
    CALCULATETABLE (
        SUMMARIZECOLUMNS (
        DimDate[CalendarYear],
        DimDate[EnglishMonthName],
        "Sales", CALCULATE (
            [Sales],
            'Time Intelligence'[Time Calculation] = "Current",
            'Averages'[Average Calculation] = "No Average"
        ),
        "YTD", CALCULATE (
            [Sales],
            'Time Intelligence'[Time Calculation] = "YTD",
            'Averages'[Average Calculation] = "No Average"
        ),
        "Daily Average", CALCULATE (
            [Sales],
            'Time Intelligence'[Time Calculation] = "Current",
            'Averages'[Average Calculation] = "Daily Average"
        ),
        "YTD Daily Average", CALCULATE (
            [Sales],
            'Time Intelligence'[Time Calculation] = "YTD",
            'Averages'[Average Calculation] = "Daily Average"
        )
    ),
    DimDate[CalendarYear] = 2012
)

平均查詢返回

下表顯示瞭如何計算三月2012的值。

平均查詢返回
列名稱計算
YTD Jan,二月,三月2012的銷售總額
= 495364 + 506994 + 373483
每日平均 三月2012的銷售額除以3月份的天數
= 373483/31
每日 YTD 平均值 三月2012的 YTD 除以一月、二月和三月的天數
= 1375841/(31 + 29 + 31)

下面是已應用優先順序為20的 YTD 計算項的定義。

DAX
CALCULATE(SELECTEDMEASURE(), DATESYTD(DimDate[Date]))

下面是應用優先順序為10的每日平均值。

DAX
DIVIDE(SELECTEDMEASURE(), COUNTROWS(DimDate))

由於時間智慧計算組的優先順序高於平均計算組的優先順序,因此它會盡可能廣泛地應用。YTD 每日平均計算同時應用於每日平均計算的分子和分母(天數的計數)。

這等效於以下表達式:

DAX
CALCULATE(DIVIDE(SELECTEDMEASURE(), COUNTROWS(DimDate)), DATESYTD(DimDate[Date]))

不是此表示式:

DAX
DIVIDE(CALCULATE(SELECTEDMEASURE(), DATESYTD(DimDate[Date])), COUNTROWS(DimDate)))

側向遞迴

在上述時間智慧示例中,某些計算項引用相同計算組中的其他項。這稱為 "側向遞迴"。例如,同比變化率%引用同比變化率和PY。

DAX
DIVIDE(
    CALCULATE(
        SELECTEDMEASURE(),
        'Time Intelligence'[Time Calculation]="YOY"
    ),
    CALCULATE(
        SELECTEDMEASURE(),
        'Time Intelligence'[Time Calculation]="PY"
    )
)

在這種情況下,這兩個表示式是單獨計算的,因為它們使用的是不同的計算語句。不支援其他型別的遞迴。

篩選上下文中的單個計算項

在我們的時間智慧示例中,PY YTD計算項具有一個計算表示式:

DAX
CALCULATE(
    SELECTEDMEASURE(),
    SAMEPERIODLASTYEAR(DimDate[Date]),
    'Time Intelligence'[Time Calculation] = "YTD"
)

計算()函式的 YTD 引數重寫篩選器上下文,以重用已在 YTD 計算項中定義的邏輯。不能將 PY 和 YTD 應用於單個評估中。僅當計算組中的單個計算項在篩選器上下文中時,才應用計算組。

排序

預設情況下,當計算組中的列放置在報表中時,計算項按名稱的字母順序在報表中排序。計算項在報表中的顯示順序可以通過指定 "序號" 屬性來更改。用 Ordinal 屬性指定計算項順序並不會改變優先順序,即計算計算項的順序。它也不會更改計算項在表格模型資源管理器中的顯示順序。

若要指定計算項的序號屬性,必須將第二列新增到計算組。與資料型別為 Text 的預設列不同,用於對計算項進行排序的第二列的資料型別為整數。此列的唯一用途是指定計算組中的計算項的顯示數值順序。由於此列在報表中未提供任何值,因此最好將Hidden屬性設定為 True。

在將第二列新增到計算組之後,您可以指定要排序的計算項的序號屬性值。

若要了解詳細資訊,請參閱對計算項進行排序。

建立計算組

在 Visual Studio 中支援計算組,Analysis Services 專案 VSIX 更新2.9.2 和更高版本。還可以通過使用表格模型指令碼語言(TMSL)或開源表格編輯器來建立計算組。

使用 Visual Studio 建立計算組

  1. 在表格模型資源管理器中,右鍵單擊 "計算組",然後單擊 "新建計算組"。預設情況下,新的計算組將具有單個列和一個計算項。

  2. 使用屬性來更改名稱,並輸入計算組、列和預設計算專案的描述。

  3. 若要為預設計算項輸入 DAX 公式表示式,請右鍵單擊,然後單擊 "編輯公式" 以開啟 DAX 編輯器。請輸入有效的表示式。

  4. 若要新增其他計算項,請右鍵單擊 "計算項",然後單擊 "新建計算項"。

訂購計算項

  1. 在表格模型資源管理器中,右鍵單擊某個計算組,然後單擊 "新增列"。

  2. 命名列序號(或類似的內容),輸入說明,然後將Hidden屬性設定為 True。

  3. 對於要進行排序的每個計算項,請將Ordinal屬性設定為正數。每個數字都是連續的,例如,序號屬性為1的計算項將首先出現,屬性2將顯示第二個,依此類推。排序中不包含預設值為-1 的計算項,但會顯示在報表中排序項之前。

限制

不支援對計算組表定義的物件級別安全性(OLS)。但是,可以在同一模型中的其他表上定義 OLS。如果計算項指的是 OLS 保護的物件,則會返回一般錯誤。

不支援行級別安全性(RLS)。在同一模型中的表上定義 RLS,而不是在計算組本身上定義(直接或間接)。

計算組不支援詳細資訊行表示式。