概述
SUM()是一個聚合函數。在應用將影響公式的所有過濾器后,它會將您指定的單個列中的所有值相加。SUM()不知道行的存在(它不能逐行求值) - 它所能做的就是在應用過濾器之后將所有內容添加到它所呈現的單列中。
SUMX()是一個迭代器函數。它應用於一個表,一行一行地應用所有過濾器后完成求值。 SUMX()具有表中行的感知,因此可以引用每行與表中任何列的交集。SUMX()可以在單個列上運行,但也可以在多個列上運行 - 因為它具有逐行工作的能力。
綜上所述
·SUM()在單個列上運行,並且不知道列中的各個行(沒有逐行求值)。
·SUMX()可以對表中的多個列進行操作,並且可以在這些列中完成逐行求值。
這兩個功能可以最終給你同樣的結果(也許是,也許不是)。它們通常在矩陣給出相同的結果,但通常在視覺的子總數和總計部分中給出不同的結果。
SUM()函數
語法:= SUM(<列名>)
示例:總銷售額= SUM(銷售表[銷售額])
SUM()函數在單個數據列上運行,以聚合該單個列中的所有數據並應用當前過濾器 - 首先過濾,然后評估第二個。
SUMX()函數
語法:= SUMX(<Table>,<expression>)
示例:總銷售額SUMX = SUMX(銷售表,銷售表[數量] *銷售表[單位價格])
SUMX()將迭代第一個參數中指定的表,一次一行,並完成第二個參數中指定的計算,例如數量x單位價格,如上例所示,當前過濾器已應用(即仍然首先過濾,求值第二)。一旦它對指定表中的每一行(在應用當前過濾器之后)完成此操作,它就會累計所有逐行計算的總和以獲得總計。結果返回此總數。
那么我應該使用哪一個呢?
您使用哪種方式取決於您的個人偏好和數據結構。我們來看幾個例子。
1數量和每單位價格
2延期金額
3總計不要加起來
1.數量和價格

如果您的銷售表包含數量列和“單價”的另一列(如上所示),那么您必須將“數量”乘以“單價”以便獲得總銷售額。將總量SUM(數量)加起來並將其乘以平均單價是不合適的,因為這將給出錯誤的答案。
如果您的數據以這種方式構建(如上圖所示),那么您只需要使用SUMX() - 這就是迭代器函數的設計目的。這是公式的樣子。
總銷售額1 = SUMX(銷售表,銷售表[數量] *銷售表[單價])
2.延期金額
如果您的數據包含具有該行項目的擴展總銷售額的單個列(即,它沒有每單位的數量和價格),則可以使用 SUM()來累加值。

總銷售額2 = SUM(銷售表[銷售額])
在此示例中不需要迭代器,因為在這種情況下,它只是跨單個列的簡單計算,並且不需要逐行執行。但請注意,你仍然可以使用SUMX()(如下所示),它會給你相同的答案。
總銷售額2替代= SUMX(銷售表,銷售表[銷售額])
並且使用SUMX()的替代公式在性能和效率上與SUM()是相同的.
3.總計不要加起來
當你必須使用不那么明顯的SUMX()時,還有另一個用例。當您遇到總計不按需要/期望加起來的問題時,您將需要使用像SUMX這樣的迭代器來糾正問題。我已經創建了一個小樣本數據表來解釋。

上表顯示了4位客戶,他們每次購物時平均花費的金額以及他們購物的次數。如果我將這些數據加載到Power BI中,然后嘗試使用聚合器函數來查找所有客戶的平均支出以及花費的總金額,我會在總行中得到錯誤的答案(如下所示)。

以下是上述措施:
總訪問次數= SUM(購物表[訪問次數]) - 該公式的總數是正確的。
每次訪問平均花費=AVERAGE(購物表 [每次訪問花費]) - 這里的總數是錯誤的。
總支出= [每次訪問費用] * [訪問總次數] - 這里的總數也是錯誤的。
第一個度量[訪問總數]是正確的,因為數據是加性的,但其他2個度量給出了錯誤的結果。這是一個典型的情況,你無法在總體水平上對平均值進行乘法運算。鑒於我開始使用的樣本數據,計算正確答案的唯一方法是為表中的每個客戶完成逐行評估,如下所示。

在上面的第二個表中,我編寫了一個SUMX()來首先創建Total Spent SUMX(逐行)。只有這樣我才能計算每次訪問的平均花費作為最終公式。
總訪問次數= SUM(購物表[訪問次數])
總花費= SUMX(購物表,購物表 [每次訪問花費] *購物表[訪問次數])
每次訪問平均花費= DIVIDE([總花費SUMX], [總訪問量])
在第二種情況下,SUMX正在一次一行地處理數據表並正確計算結果,即使對於表底部的總行也是如此。
性能影響存儲引擎
我要談的最后一件事是使用SUM與SUMX的性能影響。鑒於SUMX是一個迭代器,您可能認為SUMX本質上是低效的。一般來說,這不是真的,因為軟件已經過優化以有效地處理場景。話雖如此,糟糕的DAX肯定會導致SUMX效率低下。
Power Pivot有2個計算引擎,存儲引擎(SE)和公式引擎(FE)。SE更快,多線程和緩存。FE速度較慢,單線程且未緩存。這本身就是一個復雜的主題,我將只討論表面,但其含義是您應該編寫公式以盡可能利用SE。當然,如果您不確切知道如何做到這一點,這可能很難,但有一些簡單的提示可以幫助您。
1.SUM()總是使用SE進行計算,因此無需擔心。
2.對於大多數簡單的計算(如Sales [數量] *銷售[單位價格]),SUMX()也將使用SE,所以那里都很好。
3.在某些情況下,SUMX()可以使用FE執行部分或全部計算,特別是如果公式中有復雜的比較語句。如果SUMX需要使用FE,那么性能可能會很慢 - 有時非常慢。
關於第3點,最好建議是避免在SUMX函數中編寫復雜的條件語句,如“IF語句”。考慮以下兩個公式:
物品總銷售額超過100美元
= SUMX(銷售,
IF(銷售[ExtendedAmount]> 100,銷售[ExtendedAmount])
)
物品總銷售額超過100美元
=CALCULATE
(
SUMX(銷售,銷售[ExtendedAmount]),
銷售[ExtendedAmount]> 100
)
第一個公式(Bad)在SUMX中有一個IF語句。此IF語句強制存儲引擎將求值任務傳遞給公式引擎以進行比較檢查,以確定每個單獨的行是否大於100,然后再決定是否將其包括在計算中。因此,公式引擎必須一次完成一行任務,使評估變得緩慢且低效。
第二個公式(Good)首先使用CALCULATE()修改來自visual的初始過濾器,以在Sales [ExtendedAmount]> 100上添加額外的過濾器。這個新過濾器由存儲引擎非常有效地應用。在CALCULATE()修改過濾器之后,SUMX()可以完成其工作,即使用存儲引擎(而不是公式引擎)應用新的過濾器集合來添加剩余的行。結果,這第二個公式非常有效。在我完成的一些簡單測試中,第一個(壞)公式比第二個(好)公式慢了5倍。在其他情況下,它可能會慢100或甚至1000倍,所以這顯然可能是一個問題。
壓縮對性能的影響
可影響性能的第二個領域是整體數據模型壓縮。數據模型中的列中存在的唯一值越多,數據的壓縮程度就越低。數據壓縮得越少,所需的內存就越多,計算速度就越慢。讓我們再看一下本文前面的表格。
示例表1

示例表1[Total Sales]數據列具有所有唯一值。此列不能很好地壓縮。
示例表2

在此表中,Qty列中還有重復值,還有每單位價格列。列中的唯一值越少,壓縮越好。
當然,這兩個樣本表當然非常小,但想象一下這個概念對非常大的表(例如具有數百萬行數據的表)的影響。對於非常大的表,示例表1中的唯一值的數量可能遠遠大於示例表2中的列中的唯一值的數量。因此,如示例2中所述的加載數據可能具有對總表大小產生積極影響,從而影響數據模型的性能。做出改變當然可能意味着你必須交換你的措施:
SUM(銷售[總銷售額])
至
SUMX(銷售,銷售[數量] *銷售[單位價格])
SUMX比起SUM的這種用法非常精細並且有更高的性能。
1.Power BI免費下載:http://www.yeacer.com/
Microsoft Power BI Desktop中文最新版:下載地址
2.歡迎加入的Power BI技術群,目前正在學習階段,有興趣的朋友可以一起學習討論。
Power Data技術交流群:702966126 (驗證注明:博客園Power BI)
更多精彩內容請關注微信公眾號:悅策PowerBI
如果您覺得閱讀本文對您有幫助,請點一下“推薦”按鈕,您的“推薦”將是我最大的寫作動力!歡迎各位轉載,作者博客:https://www.cnblogs.com/yeacer/
