DAX 查找无关 table 中的第一个非空白值
DAX lookup first non blank value in unrelated table
如何在 unrelated table 中查找第一个非空值。我想要相当于:
- SQL
outer apply (select top 1 ...)
或
- Excel
VLOOKUP
.
该代码中使用的 DAX LOOKUPVALUE
函数不起作用。
LOOKUPVALUE(
SearchTable[name]
, SearchTable[id] -- how to get the fist value, if here are multiple id?
, ThisTable[id]
)
DAX LOOKUPVALUE
函数工作正常,如果只返回一个唯一值作为结果。函数 LOOKUPVALUE
returns 错误消息,如果在搜索中找到多个值 table for one key:
A table of multiple values was supplied where a single value was
expected.
我不想要错误消息,我对前 1 个结果感到满意。
示例数据文件:
对接受的答案发表评论
我最喜欢 Alexis Olson 的第二种方法,尽管我更喜欢 VAR
而不是 EARLIER
变体:
MyLookup =
var LookupKey = ThisTable[Product]
return
CALCULATE (
MAX ( SearchTable[Category] ),
SearchTable[Product] = LookupKey
)
我接受了它,尽管我有一种强烈的感觉这不是可能存在的最佳答案。函数 returns MAX
而不是 TOP 1
这显然是额外的努力。
示例数据现在包含 4 个工作解决方案。我已经根据自己的喜好对它们进行了编号。前两个是亚历克西斯奥尔森。据我从 DAX Studio 中了解到的情况,这两种解决方案都同样快速并且具有简单的执行计划。第二种解决方案是唯一只执行两次 table 扫描的解决方案(所有其他方法都有 3 次扫描)。第三种方案执行计划复杂,第三次扫描时遍历整个搜索table,不管是不是百万行。
这个问题有一个后续问题,我在其中尝试比较 Dax Studio 中的查询:
How to check in Daxstudio which DAX query has better performance?
更新寻求进一步改进
我想知道是否有可能实现比当前获胜答案更短的查询计划。获胜代码将在 DaxStudio 中进行评估,并且查询计划应该比查询计划的物理行和逻辑行总共 20 行更短。
-- Bounty code
EVALUATE
ADDCOLUMNS (
VALUES ( ThisTable[Product] ),
"FilterLookup",
VAR LookupKey = ThisTable[Product]
RETURN
CALCULATE ( MAX ( SearchTable[Category] ), SearchTable[Product] = LookupKey )
)
有一个 FIRSTNONBLANK(column, expression) 函数。没有帮助吗?
试试这个:
Column =
VAR row_id = ThisTable[id]
VAR ret_val =
SELECTCOLUMNS (
TOPN (
1;
CALCULATETABLE (
SearchTable;
SearchTable[id] = row_id;
SearchTable[name] <> BLANK ()
)
);
"name"; SearchTable[name]
)
RETURN
ret_val
有很多方法可以做到这一点。以下是我想到的前三名:
这是一个最简单的查找函数,但仅当 SearchTable
中的每个产品都有一个关联类别时才有效。
LookupFunction =
LOOKUPVALUE ( SearchTable[Category], SearchTable[Product], ThisTable[Product] )
以下遗嘱仍适用于多分类产品:
MaxxLookup =
MAXX (
FILTER ( SearchTable, SearchTable[Product] = ThisTable[Product] ),
SearchTable[Category]
)
CaclculateMaxLookup =
CALCULATE (
MAX ( SearchTable[Category] ),
SearchTable[Product] = EARLIER ( ThisTable[Product] )
)
如果您想将第 2 或第 3 作为度量而不是计算列,则需要对其进行调整。
注意: 以上工作正常作为 计算列 。如果您希望它们同时用作计算列和度量,请按如下方式调整它们:
LookupMeasure =
LOOKUPVALUE (
SearchTable[Category],
SearchTable[Product], CALCULATE ( SELECTEDVALUE ( ThisTable[Product] ) )
)
MaxxMeasure=
VAR CurrProduct = CALCULATE ( SELECTEDVALUE ( ThisTable[Product] ) )
RETURN
MAXX (
FILTER ( SearchTable, SearchTable[Product] = CurrProduct ),
SearchTable[Category]
)
CaclculateMaxMeasure =
VAR CurrProduct = CALCULATE ( SELECTEDVALUE ( ThisTable[Product] ) )
RETURN
CALCULATE ( MAX ( SearchTable[Category] ), SearchTable[Product] = CurrProduct )
不同之处在于,当您编写计算列时,行上下文会告诉您要使用哪个产品。编写度量时,需要指定要使用的 ThisTable[Product]
列中的哪个值。
注意:如果您的过滤器上下文中有多个产品,并且您希望度量查找最大产品的类别,请使用 MAX
而不是 SELECTEDVALUE
。如果有多个值,后者将 return 为空白。
编辑:
以上公式适用于提供的原始数据集。但是,如果 SearchTable
中有多个类别与单个产品关联,则 LOOKUPVALUE
函数将中断(因为它只需要一个值),您将需要使用 MAX
或 MAXX
版本。
我想我解决了这个问题:
Measure0 是测量
Measure1 为计算列度量
Apple 没有 Category 因为它有 3 个类别而不能选择一个,所以它 returns 空白
Measure0 =
FIRSTNONBLANK (
SearchTable[Category],
CALCULATE (
MAX ( SearchTable[Product] ),
TREATAS ( VALUES ( ThisTable[product] ), SearchTable[Product] )
)
)
Measure1 =
CALCULATE (
FIRSTNONBLANK (
SearchTable[Category],
CALCULATE (
MAX ( SearchTable[Product] ),
TREATAS ( VALUES ( ThisTable[product] ), SearchTable[Product] )
)
)
)
如何在 unrelated table 中查找第一个非空值。我想要相当于:
- SQL
outer apply (select top 1 ...)
或 - Excel
VLOOKUP
.
该代码中使用的 DAX LOOKUPVALUE
函数不起作用。
LOOKUPVALUE(
SearchTable[name]
, SearchTable[id] -- how to get the fist value, if here are multiple id?
, ThisTable[id]
)
DAX LOOKUPVALUE
函数工作正常,如果只返回一个唯一值作为结果。函数 LOOKUPVALUE
returns 错误消息,如果在搜索中找到多个值 table for one key:
A table of multiple values was supplied where a single value was expected.
示例数据文件:
对接受的答案发表评论
我最喜欢 Alexis Olson 的第二种方法,尽管我更喜欢 VAR
而不是 EARLIER
变体:
MyLookup =
var LookupKey = ThisTable[Product]
return
CALCULATE (
MAX ( SearchTable[Category] ),
SearchTable[Product] = LookupKey
)
我接受了它,尽管我有一种强烈的感觉这不是可能存在的最佳答案。函数 returns MAX
而不是 TOP 1
这显然是额外的努力。
示例数据现在包含 4 个工作解决方案。我已经根据自己的喜好对它们进行了编号。前两个是亚历克西斯奥尔森。据我从 DAX Studio 中了解到的情况,这两种解决方案都同样快速并且具有简单的执行计划。第二种解决方案是唯一只执行两次 table 扫描的解决方案(所有其他方法都有 3 次扫描)。第三种方案执行计划复杂,第三次扫描时遍历整个搜索table,不管是不是百万行。
这个问题有一个后续问题,我在其中尝试比较 Dax Studio 中的查询:
How to check in Daxstudio which DAX query has better performance?
更新寻求进一步改进
我想知道是否有可能实现比当前获胜答案更短的查询计划。获胜代码将在 DaxStudio 中进行评估,并且查询计划应该比查询计划的物理行和逻辑行总共 20 行更短。
-- Bounty code
EVALUATE
ADDCOLUMNS (
VALUES ( ThisTable[Product] ),
"FilterLookup",
VAR LookupKey = ThisTable[Product]
RETURN
CALCULATE ( MAX ( SearchTable[Category] ), SearchTable[Product] = LookupKey )
)
有一个 FIRSTNONBLANK(column, expression) 函数。没有帮助吗?
试试这个:
Column =
VAR row_id = ThisTable[id]
VAR ret_val =
SELECTCOLUMNS (
TOPN (
1;
CALCULATETABLE (
SearchTable;
SearchTable[id] = row_id;
SearchTable[name] <> BLANK ()
)
);
"name"; SearchTable[name]
)
RETURN
ret_val
有很多方法可以做到这一点。以下是我想到的前三名:
这是一个最简单的查找函数,但仅当 SearchTable
中的每个产品都有一个关联类别时才有效。
LookupFunction =
LOOKUPVALUE ( SearchTable[Category], SearchTable[Product], ThisTable[Product] )
以下遗嘱仍适用于多分类产品:
MaxxLookup =
MAXX (
FILTER ( SearchTable, SearchTable[Product] = ThisTable[Product] ),
SearchTable[Category]
)
CaclculateMaxLookup =
CALCULATE (
MAX ( SearchTable[Category] ),
SearchTable[Product] = EARLIER ( ThisTable[Product] )
)
如果您想将第 2 或第 3 作为度量而不是计算列,则需要对其进行调整。
注意: 以上工作正常作为 计算列 。如果您希望它们同时用作计算列和度量,请按如下方式调整它们:
LookupMeasure =
LOOKUPVALUE (
SearchTable[Category],
SearchTable[Product], CALCULATE ( SELECTEDVALUE ( ThisTable[Product] ) )
)
MaxxMeasure=
VAR CurrProduct = CALCULATE ( SELECTEDVALUE ( ThisTable[Product] ) )
RETURN
MAXX (
FILTER ( SearchTable, SearchTable[Product] = CurrProduct ),
SearchTable[Category]
)
CaclculateMaxMeasure =
VAR CurrProduct = CALCULATE ( SELECTEDVALUE ( ThisTable[Product] ) )
RETURN
CALCULATE ( MAX ( SearchTable[Category] ), SearchTable[Product] = CurrProduct )
不同之处在于,当您编写计算列时,行上下文会告诉您要使用哪个产品。编写度量时,需要指定要使用的 ThisTable[Product]
列中的哪个值。
注意:如果您的过滤器上下文中有多个产品,并且您希望度量查找最大产品的类别,请使用 MAX
而不是 SELECTEDVALUE
。如果有多个值,后者将 return 为空白。
编辑:
以上公式适用于提供的原始数据集。但是,如果 SearchTable
中有多个类别与单个产品关联,则 LOOKUPVALUE
函数将中断(因为它只需要一个值),您将需要使用 MAX
或 MAXX
版本。
我想我解决了这个问题: Measure0 是测量 Measure1 为计算列度量 Apple 没有 Category 因为它有 3 个类别而不能选择一个,所以它 returns 空白
Measure0 =
FIRSTNONBLANK (
SearchTable[Category],
CALCULATE (
MAX ( SearchTable[Product] ),
TREATAS ( VALUES ( ThisTable[product] ), SearchTable[Product] )
)
)
Measure1 =
CALCULATE (
FIRSTNONBLANK (
SearchTable[Category],
CALCULATE (
MAX ( SearchTable[Product] ),
TREATAS ( VALUES ( ThisTable[product] ), SearchTable[Product] )
)
)
)