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 的存在導致性能不佳的情況。
參考文檔: