[知识体系] 理解 SELECTEDVALUE

  [复制链接]
查看129257 | 回复130 | 2021-2-21 18:58:59 | 显示全部楼层 |阅读模式
SELECTEDVALUE
  1. SELECTEDVALUE ( <ColumnName>, [<AlternateResult>] )
复制代码

当指定列中只有一个值时返回该值,否则返回备选结果,省略备选结果时返回空值。


SELECTEDVALUEIF+HASONEVALUE 等价,而且公式更简洁。
  1. SELECTEDVALUE ( Table[column] )
  2. SELECTEDVALUE ( Table[column], "default value" )
  3. SELECTEDVALUE ( Table[column], 0 )

  4. ------- 等价于 ---------

  5. IF ( HASONEVALUE ( Table[column] ), VALUES ( Table[column] ) )
  6. IF ( HASONEVALUE ( Table[column] ), VALUES ( Table[column] ), "default value" )
  7. IF ( HASONEVALUE ( Table[column] ), VALUES ( Table[column] ), 0 )
复制代码

当需要获取筛选上下文中的单个值时,推荐使用 SELECTEDVALUE,因为它的语法更简洁,并且在遇到多值情况的时候,SELECTEDVALUE 可以返回空白或设定的默认值来容错。


SELECTEDVALUE 在内部使用了 VALUES,由于 VALUES 考虑参照完整性,因此,当使用 SELECTEDVALUES 编写的计算列用于创建关系时可能遇到空行依赖的问题,用 DISTINCT 代替 VALUES 可以解决此类问题。

总结

  • SELECTEDVALUE 和 VALUES 函数获取当前筛选上下文,而不是行上下文;
  • 当具有行上下文时,直接引用列即可获取当前行的值(如果列位于关系「一」端的表,可以使用 RELATED);
  • 如果引用的列在筛选上下文中返回空行,则 SELECTEDVALUE 返回第二个参数。不要假设仅当选择了两个或更多值时才返回第二参数;
  • 如果 Excel 或 SSAS 版本较低,没有 SELECTEDVALUE 函数,可以使用 HASONEVALUE 和 VALUES 代替;

用法示例
从同一张表中获取列值

比如从产品表中获取产品等级(Product Class)展示在下面的表格中



7103211936391.png

  1. Product Class := SELECTEDVALUE ( 'Product'[Class] )
复制代码

这种写法有一个问题,没有销售额的产品也会返回对应的等级,如果要避免这种情况,可以加一个条件判断。
  1. Product Class v1 :=
  2. IF (
  3.     NOT ISBLANK ( [Sales Amount] ),
  4.     SELECTEDVALUE ( 'Product'[Class] )
  5. )

  6. Product Class v2 :=
  7. IF (
  8.     NOT ISEMPTY ( Sales ),
  9.     SELECTEDVALUE ( 'Product'[Class] )
  10. )
复制代码

7103211936392.png

新的写法不会显示销售额为空的记录

从维表中获取指定列的值

当需要从关系的多端出发获取关系一端的值时,如果存在行上下文(比如计算列),可以直接使用 RELATED,无论是否存在中间表,RELATED 将穿过这些关系获取指定的列值;如果是在度量值的环境中,你需要修改筛选上下文在关系中的传递方向。以产品、产品子类别和产品类别三张表的关系为例,如果你想在矩阵或数据透视表中获得当前产品的类别,可以使用以下代码:
  1. Product Category :=
  2. CALCULATE (
  3.     SELECTEDVALUE ( 'Product Category'[Category] ),
  4.     CROSSFILTER (
  5.         'Product'[ProductSubcategoryKey],
  6.         'Product Subcategory'[ProductSubcategoryKey],
  7.         Both
  8.     ),
  9.     CROSSFILTER (
  10.         'Product Subcategory'[ProductCategoryKey],
  11.         'Product Category'[ProductCategoryKey],
  12.         Both
  13.     )
  14. )
复制代码

使用扩展表,还有一种简单的写法
  1. Product Category exp.table :=
  2. CALCULATE (
  3.     SELECTEDVALUE ( 'Product Category'[Category] ),
  4.     'Product'
  5. )
复制代码

扩展表一文中你会了解到,复杂的数据模型中,依赖扩展表很可能会带来意料之外的副作用,因此建议首选 CROSSFILTER 函数作为解决方案。


7103211936393.png

两种写法结果相同

在计算中引用数值列

SELECTEDVALUE 简化了在计算中使用数值列(物理列)作为参数时的语法。例如,下面的度量值用销售额除以所选产品的单价,以计算销售数量。如果选择了多个产品,SELECTEDVALUE 将返回空白,Calc Quantity 也将是空值。
  1. Calc Quantity :=
  2. DIVIDE (
  3.     [Sales Amount],
  4.     SELECTEDVALUE ( 'Product'[Unit Price] )
  5. )
复制代码

7103211936394.png

Audio 行自动返回空

从参数表返回所选参数



简化 IF + HASONEVALUE 的写法
  1. Sales by Scale :=
  2. DIVIDE (
  3.     [Sales Amount],
  4.     SELECTEDVALUE ( 'Scale'[Scale], 1 )
  5. )

  6. ---------- 简化下面公式 ----------

  7. Sales by Scale := 
  8. DIVIDE (
  9.     [Sales Amount],
  10.     IF ( HASONEVALUE ( Scale[Scale] ), VALUES ( Scale[Scale] ), 1 )
  11. )
复制代码


7103211936395.png



当用户不小心选择多个参数的时候,公式将使用 1 作为分母,如果你想在发生这种情况的时候弹出人性化的提示,可以使用 ERROR 函数
  1. Sales by Scale Checked :=
  2. DIVIDE (
  3.     [Sales Amount],
  4.     SELECTEDVALUE ( 'Scale'[Scale], ERROR ( "Single selection required" ) )
  5. )
复制代码
7103211936396.zip (1.29 MB, 下载次数: 0)
回复

使用道具 举报

天山村夫 | 2021-4-24 15:18:33 | 显示全部楼层
为了三千积分!
回复

使用道具 举报

Turbo | 2021-5-2 20:31:08 | 显示全部楼层
小白一个 顶一下
回复

使用道具 举报

独行侠 | 2021-5-4 15:46:55 来自手机 | 显示全部楼层
锄禾日当午,发帖真辛苦。谁知坛中餐,帖帖皆辛苦!
回复

使用道具 举报

咖啡豆 | 2021-6-16 19:25:00 | 显示全部楼层
元芳你怎么看?
回复

使用道具 举报

zws107 | 2021-6-21 15:34:54 来自手机 | 显示全部楼层
有空大家一起交流一下
回复

使用道具 举报

什么 | 2021-8-21 13:01:47 | 显示全部楼层
锄禾日当午,发帖真辛苦。谁知坛中餐,帖帖皆辛苦!
回复

使用道具 举报

zhoubaozhoubao | 2021-9-2 10:08:53 来自手机 | 显示全部楼层
有空大家一起交流一下
回复

使用道具 举报

ysy555 | 2021-10-5 06:13:48 | 显示全部楼层
前排顶,很好!
回复

使用道具 举报

维维 | 2021-10-11 08:49:30 来自手机 | 显示全部楼层
路过 帮顶 嘿嘿
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则