DAX中按列排序的另一種結果


​今天,小悅和大家分享一篇國外知名大咖的一篇文章:DAX中“按列排序”的所產生的另一種結果。

Power BI中的“按列排序”功能會導致產生副作用,這些副作用在編寫DAX公式時必須了解。本文介紹了這些副作用以及如何編寫正確的DAX代碼以避免產生錯誤的結果。

 

按列排序功能:使用來自另一列的值對列的值進行排序。

例如,報表設計員可能希望按一月,二月和三月的順序按名稱顯示月份。因此,按列排序屬性應用“Month Name”列,使用“Month Number”列定義月份名稱的排序順序。這樣可以避免按字母排序得到你不想要的值。

 

 

DAX和MDX中的列排序順序

MDX中的查詢會自動從數據模型繼承正確的列排序順序。MDX查詢的結果始終根據“按列排序”設置進行排序。但是,除了基礎數據類型的自然排序順序以外,DAX對列沒有任何隱式排序順序。

因此,DAX查詢必須始終在ORDER BY條件中指定排序順序,這與SQL查詢類似。因為DAX要求將ORDER BY中使用的列作為查詢結果的一部分,所以對BI列進行排序的Power BI視覺總是會生成一個查詢,該查詢至少包括兩列:報表中請求的列和報表中使用的基礎列-按列排序設置。換句話說,按月顯示數據的Power BI視覺圖必須生成一個包含月名稱和月號的查詢。例如,參考Power BI中的以下報告:

 

 

DAX生成的查詢如下:

EVALUATE

TOPN (

   502,

   SUMMARIZECOLUMNS (

       ROLLUPADDISSUBTOTAL (

           ROLLUPGROUP (

               'DATE'[MONTH NAME],

               'DATE'[MONTH NUMBER]

           ), "ISGRANDTOTALROWTOTAL"

       ),

       "SALESAMOUNT", 'SALES'[SALESAMOUNT]

   ),

   [ISGRANDTOTALROWTOTAL], 0,

   'DATE'[MONTH NUMBER], 1,

   'DATE'[MONTH NAME], 1

)

ORDER BY

   [ISGRANDTOTALROWTOTAL] DESC,

   'DATE'[MONTH NUMBER],

   'DATE'[MONTH NAME]

 

盡管報告僅顯示月份名稱,但DAX查詢同時包含月份名稱和月份編號。實際上,結果已按月號正確排序。

 

現在,考慮連接到相同數據模型的Excel中的等效數據透視表,例如使用powerbi.com上的“在Excel中分析”功能。

 

 

 MDX生成的查詢如下:

SELECT

NON EMPTY

   HIERARCHIZE(

       { DRILLDOWNLEVEL(

           { [DATE].[MONTH NAME].[ALL] },

           ,,

           INCLUDE_CALC_MEMBERS

       ) }

   )

   DIMENSION PROPERTIES

       PARENT_UNIQUE_NAME,

       HIERARCHY_UNIQUE_NAME

   ON COLUMNS

FROM [MODEL]

 

MDX查詢僅包含月份名稱。不必指定月份號,因為MDX保證結果中的月份名稱屬性已經按月份號排序了。

 

DAX查詢中按列排序的副作用

兩列的存在也會對過濾器上下文產生副作用。例如,參考以下方法:

FILTERMONTHNAME :=

ISFILTERED ( 'DATE'[MONTH NAME] )

FILTERMONTHNUMBER :=

ISFILTERED ( 'DATE'[MONTH NUMBER] )

WRONG % MONTHS :=

DIVIDE (

   [SALESAMOUNT],

   CALCULATE (

       [SALESAMOUNT],

       ALL ( 'DATE'[MONTH NAME] )

   )

)

通過在Power BI和Excel中比較相似報告的結果,可以發現一些差異。

 

 

 錯誤月份百分比度量在Power BI(左側)中不起作用,因為它始終返回100%,而在Excel(右側)中則正確。

 

 

此外,ISFILTERED函數為兩個客戶端中的FilterMonthNumber列提供不同的結果:當選擇月份名稱(左側)時,Power BI始終返回TRUE,而Excel在類似的報告中返回FALSE。原因是DAX在查詢中同時包含兩列–與MDX生成的過濾器上下文相比,這將生成不同的過濾器上下文來評估度量。

 

最后,當報表使用不帶“月份名稱”的“月份編號”列時,“月份名稱”上的“按列排序”的存在不會引起任何副作用。以下Power BI報告顯示,當在矩陣的行中使用月份號時,只有FilterMonthNumber度量返回TRUE,而不會影響FilterMonthName度量。

 

 

 使用“按列排序”的度量的黃金法則

為了使使用“按列排序”設置操作列的措施具有可預測的作用,每次刪除或操作過濾器時,最好始終包括“按列排序”設置涉及的兩個列。

因此,如果要在單個列上編寫過濾器測試,如:

ISFILTERED ( 'DATE'[MONTH] )

ISFILTERED ( 'DATE'[MONTH NUMBER] )

 

最好編寫一個包含兩列的單個表達式,例如:

ISFILTERED ( 'DATE'[MONTH] ) || ISFILTERED ( 'DATE'[MONTH NUMBER] )

 

如果要在單列上除去過濾器:

ALL ( 'DATE'[MONTH] )

ALL ( 'DATE'[MONTH NUMBER] )

 

最好編寫一個包含兩列的過濾器:

ALL ( 'DATE'[MONTH], 'DATE'[MONTH NUMBER] )

 

根據這些最佳實踐進行了重寫,以前的百分比度量如下所示:

CORRECT % MONTHS :=

DIVIDE (

   [SALESAMOUNT],

   CALCULATE (

       [SALESAMOUNT],

       ALL ( 'DATE'[MONTH NAME], 'DATE'[MONTH NUMBER] )

   )

)

當在矩陣行中使用“月份名稱”時,使用最后一項度量的Power BI報告按月顯示正確的百分比。

 

 

結論

當DAX表達式從具有“按列排序”設置處於活動狀態的列中刪除過濾器時,最佳做法是始終將兩個列都包括在ALL函數中(可參考ALL的功能)。為了測試是否對列進行了過濾,最佳做法是在“ 或”條件下包括兩個ISFILTERED函數,測試“按列排序”設置中涉及的兩個列。

 

獲取案例文件

如果您喜歡該文章,並想要獲取該文章源文件的朋友們,留言獲取。

 

 往期推薦

【2019】Power BI 9月產品功能更新視頻

【2019】Power BI 9月產品功能更新文檔

● 新DAX功能:CONVERT and REMOVEFILTERS

【2019】10月份(廣州站)Power BI 線下活動報名

 

技術交流

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/ 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM