DAX:GROUPBY函數

DAX 中的 SUMMARIZE 函數功能強大,但同時也很難使用,它可用於執行表之間的分組和連接。不幸的是,它在計算聚合值時存在一些衆所周知的性能問題。除了性能之外,SUMMARIZE 的計算限制是它無法聚合在查詢本身內動態計算的值。

一,SUMMARIZE函數的限制

例如,考慮以下查詢,它應該爲每個產品類別返回相關子類別的平均價格的最大值。

ADDCOLUMNS (
    SUMMARIZE (
        ADDCOLUMNS (
            SUMMARIZE (
                Product,
                'Product Category'[Category],
                'Product Subcategory'[Subcategory]
            ),
            "Average Price", CALCULATE ( AVERAGE ( Product[Unit Price] ) )
        ),
        'Product Category'[Category]
    ),
    "Max SubCat Avg Price", CALCULATE ( MAX ( [Average Price] ) )
)

如果運行此查詢,計算 MAX ( [Average Price] ) 時會出現錯誤。 原因是在 DAX 中您只能聚合物理列(physical column)。 事實上,請記住這個等價物:

MAX ( table[expression] ) = MAXX ( table, table[expression] )

如果您嘗試聚合在查詢中計算的列(例如本例中的Average Price列),引擎將無法找到相應的 MAXX 函數,因此您會得到一個錯誤。 您可以通過重寫查詢避免嵌套的 SUMMARIZE 調用來獲得所需的結果。

ADDCOLUMNS (
    VALUES ( 'Product Category'[Category] ),
    "Max SubCat Avg Price", CALCULATE (
        MAXX (
            ADDCOLUMNS (
                SUMMARIZE (
                    Product,
                    'Product Category'[Category],
                    'Product Subcategory'[Subcategory]
                ),
                "Average Price", CALCULATE ( AVERAGE ( Product[Unit Price] ) )
            ),
            [Average Price]
        )
    )
)

除了冗長之外,這種方法效率不高。 如果您想計算最低和最高平均價格,您將複製內部 SUMMARIZE,需要更長的執行時間。

二,引入GROUPBY函數

GROUPBY 函數的語法類似於 SUMMARIZE,儘管其語義不同。 事實上,它解決了我們在對值進行分組時在 SUMMARIZE 中遇到的問題,因此您可以避免本文中描述的模式 ADDCOLUMNS/SUMMARIZE 而只依賴 GROUPBY。

然而,即使使用 GROUPBY,您也不能使用我們在開始時看到的語法,因爲聚合內部計算列的限制仍然存在。 您必須使用一個新函數 CURRENTGROUP,它允許訪問內部組,因此您具有 aggX 函數的表參數,並且您可以通過行上下文以這種方式訪問計算列。

注意:CURRENTGROUP ()函數只能用於GROUPBY 函數中。GROUPBY返回一組group,每個group有多個數據行(row),CURRENTGROUP ()函數用於從GROUPBY的結果中返回當前group。

GROUPBY (
    ADDCOLUMNS (
        GROUPBY (
            Product,
            'Product Category'[Category],
            'Product Subcategory'[Subcategory]
        ),
        "Average Price", CALCULATE ( AVERAGE ( Product[Unit Price] ) )
    ),
    'Product Category'[Category],
    "Max SubCat Avg Price", MAXX ( CURRENTGROUP (), [Average Price] )
)

您必須在 GROUPBY 調用中使用 CURRENTGROUP,因此您不能使用ADDCOLUMNS 函數來添加新的計算列。僅當您在不使用 CALCULATE 或引用度量的情況下顯式編寫計算時,您才能擺脫 ADDCOLUMNS:這些操作在 GROUPBY 中是不允許的(目前唯一支持的用途是在聚合函數中調用 CURRENTGROUP),因此您仍然必須依賴 ADDCOLUMNS 以防您需要過濾上下文。 因此,您可以在不使用 ADDCOLUMNS 函數的情況下使用以下語法來計算平均價格列。

GROUPBY (
    GROUPBY (
        Product,
        'Product Category'[Category],
        'Product Subcategory'[Subcategory],
        "Average Price", AVERAGEX ( CURRENTGROUP() , Product[Unit Price] )
    ),
    'Product Category'[Category],
    "Max SubCat Avg Price", MAXX ( CURRENTGROUP (), [Average Price] )
)

結論:每當您想在迭代器中訪問組的行時,您應該考慮使用 GROUPBY 而不是 ADDCOLUMNS/SUMMARIZE。 每當您有嵌套的分組操作時,這是必需的。 您可以在最裏面的組中使用 SUMMARIZE,但必須使用 GROUPBY 才能訪問在內部分組函數中計算的列。

 

參考文檔:

Nested grouping using GROUPBY vs SUMMARIZE

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章