10.1 IF 和 SWITCH


# IF 和 SWITCH

基础

IF 是最常见的逻辑函数,用于条件判断,它的语法和Excel相同。SWITCH是多层IF的简化形式,本质是IF嵌套,但是写法更优雅,以下是两个示例:———— IF形式 ——————SizeDesc =IF(DProduct[Size]=”S”,”Small”,IF(Product[Size]=”M”,”Medium”,IF(Product[Size]=”L”,”Large”,IF(Product[Size]=”XL”,”Extra Large”,”Other”))))———— SWITCH等价形式 —————SizeDesc =SWITCH(Product[Size],”S”,”Small”,”M”,”Medium”,”L”,”Large”,”XL”,”Extra Large”,”Other”)除了用第一参数返回的值作为判断条件,SWITCH还有一种实用的写法,适合用在逻辑判断中,在逻辑函数一文中介绍过,SWITCH(TRUE(),Product[Size]=”XL”&& Product[Color]=”Red”,”Red and XL”,Product[Size]=”XL”&& Product[Color]=”Blue”,”Blue and XL”,Product[Size]=”L”&& Product[Color]=”Green”,”Green and L”)使用TRUE作为第一参数表示:“返回条件求值为TRUE的第一个结果”。## 注意 IF函数看似结构简单,但隐藏了一些容易被忽视的细节。### 变体类型 变体数据类型用于可能返回不同数据类型的度量值,主要与IF配合使用,变体类型取决于度量值使用的条件表达式。例如,下面的语句可以返回整数或字符串,所以它返回一个变体类型:IF([measure]>0,1,”N/A”)变体只适用于度量值,不能用于计算列,因为计算列必须具有统一的数据类型10.1 IF 和 SWITCH - 图1计算列的必须使用统一的数据类型### 标量函数 IF和SWITCH都是标量函数,所以它们只能输出标量值,不能输出表,你不能在IF的条件中直接返回表表达式,所以下面的写法是错误的:VAR Granularity =IF(SELECTEDVALUE(‘Dynamic Axis’[Granularity])=”Monthly”,DATESMTD(‘Calendar’[date]),DATESYTD(‘Calendar’[date]))RETURNCALCULATE(SUM([SomeField]),Granularity)### 逻辑表达式的一种特殊情况 当IF的返回条件中出现一个逻辑表达式,即“true”或“false”时,整个公式返回逻辑表达式或文本,忽略数字和空值。IF(1=1,BLANK(), TRUE)返回FALSEIF(1=1,100, FALSE)返回TRUE## 使用变量优化IF和SWITCH 在DAX表达式中使用变量替换相同度量值的多次引用可以提高公式可读性、优化公式的效率,因为正确地使用变量可以防止对同一表达式多次计算。然而,在某些情况下,变量的使用也可能适得其反,对性能产生负面影响。首先,让我们演示变量如何优化公式的执行。考虑下面的报告,Sales YTDOY 计算的是今年的累计销售额与去年累计销售额的差值,仅考虑两年中都有销售额的月份10.1 IF 和 SWITCH - 图2Sales YTDOY :=CALCULATE(SUMX(VALUES(‘Date’[Calendar Year Month Number]),VAR CurrentSales =[Sales Amount]VAR PreviousSales =[Sales LY]RETURNIF(AND(CurrentSales <>0,PreviousSales <>0),CurrentSales - PreviousSales)),DATESYTD(‘Date’[Date]))Sales YTDOY 公式对于SUMX第一参数中的月份,每月只计算一次[Sales Amount]和[Sales LY],在后续的IF条件中重复调用。对比下面的公式,你会发现这种写法的效率高的多。Sales YTDOY slow :=CALCULATE(SUMX(VALUES(‘Date’[Calendar Year Month Number]),IF(AND([Sales Amount]<>0,[Sales LY]<>0),[Sales Amount]-[Sales LY])),DATESYTD(‘Date’[Date]))尽管DAX引擎可能会在相同的筛选上下文([Sales Amount]和[Sales LY])中复用相同度量获得的结果,但这种理想情况并非始终发生。在这种情况下,变量是确保更好的优化代码执行的好方法。这种理想情况称为短路计算,随着DAX引擎的更新,对于一些并不复杂的IF判断,引擎可以自动执行短路计算,以提高效率。但是对于复杂的表达式,你不能依赖引擎的判断,使用变量是最佳方法。需要注意的是,变量的计算受定义环境的影响。例如,如果变量定义在条件判断之前,则无论条件是否命中,都将计算该变量。当报告中存在独立的切片器时,这将对性能产生很大影响。要理解一点,参考下面这个报告,右侧时段选择表定义了切片器,该切片器控制矩阵的可见列,矩阵使用Sales度量值。10.1 IF 和 SWITCH - 图3sales度量值有两种定义方式,请对比两者的不同低效写法高效写法Sales vSlow =VAR PeriodSelection =SELECTEDVALUE(‘Time Selection’[PeriodSelector])VAR SalesAmount =[Sales Amount]VAR SalesLY =[Sales LY]VAR SalesYOY =[Sales YOY]VAR SalesYTD =[Sales YTD]VAR SalesLYTD =[Sales LYTD]VAR SalesYTDOY =[Sales YTDOY]RETURNSWITCH(PeriodSelection,”C”, SalesAmount,”LY”, SalesLY,”YOY”, SalesYOY,”YTD”, SalesYTD,”LYTD”, SalesLYTD,”YTDOY”, SalesYTDOY,BLANK())考虑到每个变量只使用一次,vSlow其实是一种冗余写法。不过,在实际使用中我们会使用这种形式一拖N的度量值来避免在模型中定义大量单独的度量值,使用vFast写法,可以减少公式代码量,并且获得更好的性能。### 短路计算 在这种多条件计算中,我们希望公式在命中指定的分支时才计算对应的变量。在IF和SWITCH函数的计值过程中,这种优化策略称为短路计算,它是通过将特定筛选器应用于IF和SWITCH求值分支的筛选上下文来实现的。由于Sales vSlow度量值中的变量是在IF和SWITCH之前定义的,因此筛选上下文的更改不适用于变量的计算。所有变量(和所有度量值)的计算将不考虑示例报表的区间切片器中所做的选择。### 变量使用规范 在特定场景中,此特性可能对DAX度量值的性能产生严重影响,因此,使用变量最好遵循以下规则:

  1. 当在同一筛选上下文中多次计算同一DAX表达式时,请将其定义为变量并在后续计算时引用该变量,而不是引用DAX表达式。
  2. 当在IF或SWITCH的分支中计算DAX表达式时,只要有必要,请在条件分支中将表达式定义为变量-这将保持短路优化。
  3. 如果仅在条件分支中使用变量,请不要在IF和SWITCH语句之外分配变量。
  4. IF和SWITCH的第一个参数可以使用在IF和SWITCH之前定义的变量,这不会影响性能。 关于第三条中,你可以用下面的公式理解IF(,— 条件分支1VAR variablename = RETURN ,— 条件分支2VAR variablename2 = RETURN ,) 参考阅读:印象笔记邮件分享标签:条件判断函数上一篇ALLSELECTED### 相关推荐
  • 暂无文章

    说点什么

    My content and settings您是token|登出token  订阅本文评论 