[知识体系] 理解变量

  [复制链接]
查看202898 | 回复163 | 2021-2-21 19:32:53 | 显示全部楼层 |阅读模式
本帖最后由 XF 于 2021-2-22 14:56 编辑
学会使用变量对于编写 DAX 非常重要,因为变量提高了代码可读性和公式的性能

初识变量

编写 DAX 表达式时,可以通过使用变量避免重复书写相同的表达式。例如,我们来看下面这个表达式:

  1. VAR Denominator =
  2. SUMX ( Sales, Sales[SalesAmount] + Sales[TotalProductCost] )
  3. VAR Numerator = SUM ( Sales[SalesAmount] )
  4. RETURN
  5. DIVIDE ( Numerator, Denominator )
复制代码


你可以定义许多变量,它们是表达式的局部变量,也就是只对当前表达式生效,不能跨度量值使用。比如下面这种写法是错误的,原因是变量 B 只存在于度量值 1 中:

  1. 度量值 1 = VAR A=1 VAR B=2 RETURN A+B
  2. 度量值 2 = VAR C=3 RETURN B+C
复制代码


和定义变量类似的还有一种 DEFINE MEASURE 的用法,在编写查询时使用,关于这两种用法详细介绍请参考 EVALUATE。


变量对于简化代码非常有用,因为避免了重复相同的子表达式。变量使用惰性计算,这意味着,如果你定义了一个变量,无论出于什么原因,如果没有被使用,那么这个变量将永远不会被计算。如果需要计算,那么计算只在首次调用时发生一次:后续对变量的调用都将读取先前计算出的值。因此,当你多次使用复杂表达式时,定义变量也可以作为优化技术使用。

正如你将在下面看到的,变量使用的是被定义时的计值上下文,不是被调用时的上下文,这个概念非常有用。

变量与计值上下文

使用变量让代码更易阅读,还可以避免多次重复相同的子表达式,但考虑到它们与计值上下文交互的方式,变量还有一个非常重要的特点,即:变量在被定义的计值上下文中计算,而不在使用它们的环境中计算,一旦变量被计算,它的值就不在变化。


当你希望在复杂公式中使用来自之前计值上下文的计算结果时,这个特性会非常有用。我们来看一个例子。假设你想用数据透视表来显示类别,并且对于每个类别,显示高销售额产品的数量。高销售额产品的定义是:一种产品的销售额超过该类别总销售额的 10%。你可以在下图看到最终效果。


7145211936391.jpeg

透视表显示了每个类别中有多少高销售额的产品


用变量来计算这个度量值很容易,而且使用变量也让公式变得更容易阅读,如下所示:

  1. [HighSalesProducts] :=
  2. VAR TenPercentOfSales = [SalesAmount] * 0.1
  3. RETURN
  4.     COUNTROWS (
  5.         FILTER (
  6.             Product,
  7.             [SalesAmount] >= TenPercentOfSales
  8.         )
  9.     )
复制代码


这个公式的有趣之处在于,DAX 在 FILTER 迭代的外部计算变量 TenPercentOfSales。如果 TenPercentOfSales 的计算是在迭代时进行的,由于发生了上下文转换,它将计算当前迭代产品 10%的销售额,这会使得整个度量值计算错误。相反,DAX 在迭代的外部计算了变量,在内部使用它,这样就可以在当前筛选上下文之外引用表达式的值。如果你想在不使用变量的情况下写出同样的度量值,你需要这样写:

  1. [HighSalesProductsCalculate] :=
  2. COUNTROWS (
  3.     FILTER (
  4.         Product,
  5.         [SalesAmount]
  6.             >= CALCULATE ( [SalesAmount], ALL ( Product ), 'Product Category' ) * 0.1
  7.     )
  8. )
复制代码


后一种代码更难读懂,因为你需要在迭代函数中重新构建出之前的计值上下文环境,这不是一项容易的任务,即使对于经验丰富的 DAX 程序员也是如此。实际上,你将会在理解筛选上下文中了解到此表达式的所有知识,在那里,我们将揭示筛选上下文的所有细节。

小测试

下面两个度量值在相同的环境中计值,它们的结果一样吗?

  1. Measure A = CALCULATE([Total Sales],Color[Color]="White")

  2. Measure B = VAR TotalSales = [Total Sales]
  3.             RETURN CALCULATE(TotalSales,Color[Color]="White")
复制代码


        
游客,如果您要查看本帖隐藏内容请回复

         
如果你发现可以使用变量来简化计算,比如代替计值上下文中的 EARLIER,那么我们很高兴地欢迎你加入 DAX 高手的行列。如果没有,不要担心。这种情况对于第一次阅读的新人是很正常的。接下来仍有许多内容专门介绍这些复杂的知识,它们将帮助你获得掌握计值上下文所需的技能

回复

使用道具 举报

薄荷 | 2021-4-24 18:48:59 | 显示全部楼层
顶起顶起顶起
回复

使用道具 举报

zhouqh | 2021-6-16 17:12:44 | 显示全部楼层
我也来支持一下,很喜欢这里老师
回复

使用道具 举报

wyfrog | 2021-10-20 18:35:09 来自手机 | 显示全部楼层
大人,此事必有蹊跷!
回复

使用道具 举报

天山村夫 | 2021-11-4 16:56:51 | 显示全部楼层
云发教育是我遇到最好的机构,和其他机构有本质区别
回复

使用道具 举报

kinsaang | 2021-11-20 10:56:10 来自手机 | 显示全部楼层
发发呆,回回帖,工作结束~
回复

使用道具 举报

燃烧寂寞的烟丝 | 2021-12-26 11:12:36 来自手机 | 显示全部楼层
路过 帮顶 嘿嘿
回复

使用道具 举报

命运奥德赛 | 2022-2-3 10:13:44 来自手机 | 显示全部楼层
在撸一遍。。。
回复

使用道具 举报

wendy | 2022-2-4 23:42:22 来自手机 | 显示全部楼层
是爷们的娘们的都帮顶!大力支持
回复

使用道具 举报

86298688 | 2022-2-10 20:52:10 | 显示全部楼层
太棒了,感谢唐楼主精彩的分享
回复

使用道具 举报

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

本版积分规则