DAX:LOOKUPVALUE 函數

LOOKUPVALUE函數用於根據一個或多個搜索條件,從另一個表中獲取一個或0個值。LOOKUPVALUE運行在行上下文中,根據當前表中的當前行,從另一個表中查找條件相等的行,查找不需要兩個表之間存在關係,搜索結果也不受過濾條件的影響。當兩個表之間存在關係時,考慮使用RELATED函數,因爲RELATED函數查詢性能更快。

LOOKUPVALUE(
    <result_columnName>,
    <search_columnName>,
    <search_value>
    [, <search2_columnName>, <search2_value>]…
    [, <alternateResult>]
)

參數註釋:

  • result_columnName:包含要返回的值的現有列的名稱,它不能是一個表達式。
  • search_columnName:現有列的名稱,它可以與 result_columnName 在同一個表中,也可以在相關表中,它不能是一個表達式。
  • search_value:要在 search_columnName 中搜索的值。
  • alternateResult:可選的參數,當 result_columnName 的上下文已過濾爲零個或多個不同值時返回的值。 如果未提供,則當 result_columnName 被過濾爲零值時該函數返回空白,或者當多個不同值時返回錯誤。

注意:

如果兩個表之間存在關係,那麼LOOKUPVALUE函數所在的表是基表,通過關係來擴展表,Search_ColumnName 可以是 Result_ColumnName 引用的擴展表的任何列。

search_value 和 alternateResult 參數在函數循環訪問搜索表的行之前進行計算。

返回值:

  • 如果沒有數據行能夠滿足所有的搜索條件,那麼函數返回 BLANK。
  • 如果存在唯一的數據行滿足所有 Search_Column 和 Search_Value 對,那麼返回該行中Result_Column的值。
  • 如果存在多行與搜索值匹配,並且Result_Column 值都相同,那麼返回該值。但是,如果 Result_Column 存在不同的值,那麼會返回錯誤。

引擎內部在執行LOOKUPVALUE函數時會生成一個等效的查詢:

VAR SearchValue = <Search_Value>
RETURN
    CALCULATE (
        SELECTEDVALUE ( <Result_ColumnName>, <Alternate_Result> ),
        FILTER (
            ALLNOBLANKROW ( <Search_ColumnName> ),
            <Search_ColumnName> == SearchValue      -- The == operator distinguishes between blank and 0/empty string
        ),
        ALL ( <table_of_Result_ColumnName> )        -- If Result_ColumnName is t[c], this is ALL ( t )
    )

一,用RELATED代替LOOKUPVALUE 

如果結果表和搜索表之間存在關係,在大多數情況下,使用 RELATED 函數而不是 LOOKUPVALUE 會更有效並提供更好的性能。

舉個例子:基於當前表Sales的SalesOrderLineKey列,通過匹配Sales Order表中SalesOrderLineKey列,獲取Sales Order表Channel字段的值。

CHANNEL = LOOKUPVALUE('Sales Order'[Channel],'Sales Order'[SalesOrderLineKey],'Sales'[SalesOrderLineKey])

由於Sales和Sales Order之間存在關係多對一的關係,可以使用RELATED函數獲得Sales Order表Channel字段的值。

CHANNEL = RELATED('Sales Order'[Channel])

二,LOOKUPVALUE的替代寫法

舉個例子,從table中獲得result_column列的值:

LOOKUPVALUE (
    table[result_column],
    table[search_column_1], <expression_1>,
    table[search_column_2], <expression_2>,
    <alternate_result>
)

根據常規的替代方法,可以得到替代方案1:

CALCULATE (
    SELECTEDVALUE ( table[result_column], <alternate_result> ),
    FILTER (
        ALLNOBLANKROW ( table[search_column_1] ),
        table[search_column_1] == <expression_1>
    ),
    FILTER (
        ALLNOBLANKROW ( table[search_column_2] ),
        table[search_column_2] == <expression_2>
    ),
    REMOVEFILTERS ( )
)

當 <expression_1> 和 <expression_2> 是常量值時,不會有任何問題。但是,通常情況下這些表達式是動態的,這可能會生成更昂貴的查詢計劃。爲了減少這個工作,您可以將表達式移到 CALCULATE 中的過濾謂詞之外,得到替代方案2:

VAR filterValue1 = <expression_1>
VAR filterValue2 = <expression_2>
RETURN CALCULATE (
    DISTINCT ( table[result_column] ),
    table[search_column_1] = filterValue1,
    table[search_column_2] = filterValue2,
    REMOVEFILTERS ( )
)

使用TREATAS函數來實現搜索條件,得到解決方案3:

CALCULATE (
    DISTINCT ( table[result_column] ),
    TREATAS ( { <expression_1> }, table[search_column_1] ),
    TREATAS ( { <expression_2> }, table[search_column_2] ),
    REMOVEFILTERS ( )
)

出於可讀性原因,最好將 TREATAS 結果存儲在變量中,但從查詢計劃的角度來看,以下代碼也與前面的代碼相同:

VAR filter1 = TREATAS ( { <expression_1> }, table[search_column_1] )
VAR filter2 = TREATAS ( { <expression_2> }, table[search_column_2] )
RETURN CALCULATE (
    DISTINCT ( table[result_column] ),
    filter1,
    filter2,
    REMOVEFILTERS ( )
)

對於 LOOKUPVALUE 用例,可以創建單個多列過濾器而不是多個過濾器——可能會產生更好的查詢計劃,得到替代方案4:

VAR filterLookup =
    TREATAS (
        { ( <expression_1>, <expression_2> ) },
        table[search_column_1],
        table[search_column_2]
    )
RETURN CALCULATE (
    DISTINCT ( table[result_column] ),
    filterLookup,
    REMOVEFILTERS ( )
)

在複雜場景中,LOOKUPVALUE 的替代方法可以優化迭代器中 LOOKUPVALUE 的存在導致性能不佳的情況。

 

參考文檔:

DAX guide - LOOKUPVALUE

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