DAX中变量的定义
- 定义:在DAX中,变量通过VAR关键字进行定义,并用于存储表达式的值。变量在定义之后,可以在后续的计算中作为参数或引用。
格式:
- 使用原则:
变量名不能使用中文名。
变量可以是一个度量值,也可以是一张表(但在实际使用中,变量通常用于存储单个值或简单计算的结果)。
变量定义后无法修改(即一旦定义了变量的值,在后续的计算中不能更改这个值)。
变量需要先定义后使用。
变量的执行逻辑
定义阶段:使用VAR关键字和表达式定义一个变量,并为其分配一个值。- 作用域:
如果变量定义在VAR...RETURN结构中,则其作用域限制在该结构内部。
如果变量定义在更高级别的公式或查询中,则其作用域可能更广。- 计算时机:
变量在定义时不会立即计算,而是等到在后续表达式中被引用时才会进行计算。
未被引用的变量不会被计算,这有助于提高查询效率。- 上下文:
变量的上下文由定义时的上下文决定,与使用时的上下文无关。
如果需要可修改的上下文,建议使用度量值(measure)而不是变量。
变量的原理- 存储机制:变量在DAX中作为一个存储数据的机制,用于存储表达式的计算结果。这些结果被存储在内存中,供后续的表达式引用。
性能优化:通过使用变量,可以避免在多个地方重复计算相同的表达式,从而提高查询性能。- 代码清晰性:将复杂的计算过程分解为多个简单的步骤,并使用变量存储中间结果,可以使代码更加清晰和易于维护。
示例
以下是一个使用VAR定义变量并计算总利润的示例:
dax
TotalProfit =
VAR SalesAmount = SUM('Sales'[Amount]); // 定义销售额变量
VAR Cost = SUM('Sales'[Cost]); // 定义成本变量
RETURN SalesAmount - Cost; // 返回销售额与成本的差值,即总利润
在这个示例中,我们首先使用VAR定义了两个变量SalesAmount和Cost,分别用于存储销售额和成本的总和。然后,我们使用RETURN语句返回这两个变量的差值,即总利润。通过使用变量,我们可以将复杂的计算过程分解为几个简单的步骤,并使代码更加清晰和易于理解。
- 在DAX中,外部上下文不会直接影响已经定义的变量的值。以下是关于DAX中变量与外部上下文关系的详细解释:
变量的定义与值:
使用VAR关键字定义的变量,其值在定义时就被计算并存储下来。
这个值是在定义变量时的上下文环境中计算得到的,一旦确定,就不会改变。
外部上下文:
在DAX中,外部上下文通常指的是查询、行上下文、筛选上下文等。
这些上下文会影响DAX表达式的计算结果,但不会直接影响已经定义的变量的值。
变量与外部上下文的关系:
变量的值是在定义时确定的,与后续使用的上下文无关。
当变量在后续的表达式中被引用时,其值会被取出并使用,而不会重新计算。
即使外部上下文发生了变化,已经定义的变量的值也不会随之改变。
示例:
假设我们有一个度量值,其中定义了一个变量来存储某个值,如:
dax
MyMeasure =
VAR MyVar = SUM('Sales'[Amount])
RETURN MyVar
在这个例子中,MyVar的值是在度量值MyMeasure被计算时确定的,具体地说是基于Sales表中Amount列的总和。无论后续查询的筛选条件如何变化,MyVar的值都是固定的,不会随着筛选条件的变化而改变。
总结:
在DAX中,变量的值是在定义时确定的,并且与外部上下文无关。
当变量在后续的表达式中被引用时,其值会被直接使用,而不是重新计算。
如果需要基于不同的上下文环境计算不同的值,应该使用度量值而不是变量。度量值会根据当前的上下文环境重新计算其值。
- 在DAX中,内部上下文通常指的是行上下文和筛选上下文,它们确实会影响变量的计算方式,但不会影响已存储的变量值本身。以下是关于DAX中变量与内部上下文关系的详细解释:
- 变量定义与存储
使用VAR关键字定义的变量,其值在定义时就被计算并存储下来。
这个值是在定义变量时的上下文环境中计算得到的,一旦确定,该值在后续的使用中不会改变。 - 内部上下文对变量的影响
a. 行上下文(Row Context)
行上下文是DAX在处理表格数据时的一种上下文,它代表了当前正在处理的行。
然而,行上下文不会影响已经定义的变量的值。变量值是在定义时确定的,与后续的行上下文无关。
b. 筛选上下文(Filter Context)
筛选上下文是通过在查询或度量值中应用的筛选器来创建的,它限定了DAX表达式中数据的范围。
筛选上下文会影响在VAR表达式中使用的任何聚合函数或计算。这是因为这些函数和计算会根据当前的筛选上下文来执行。
但筛选上下文不会改变已经定义的变量的值。变量值是在定义时确定的,与后续的筛选上下文无关。 - 示例
假设我们有一个度量值,其中定义了一个变量来存储某个筛选后的总和:
dax
FilteredTotalSales =
VAR SalesInYear = SUMX(FILTER(Sales, Sales[Year] = 2023), Sales[Amount])
RETURN SalesInYear
在这个例子中,SalesInYear变量是通过SUMX和FILTER函数计算得到的,它表示2023年的销售总额。这个值是在度量值FilteredTotalSales被计算时确定的,并且是基于Sales[Year] = 2023这个筛选条件。
如果后续查询或报表中的筛选条件发生了变化(例如,改为筛选2024年的数据),FilteredTotalSales度量值会重新计算,但这不会改变SalesInYear变量在之前计算中得到的值。相反,它会根据新的筛选条件重新计算一个新的SalesInYear值。
- 总结
在DAX中,内部上下文(行上下文和筛选上下文)会影响在VAR表达式中使用的聚合函数和计算,但不会影响已存储的变量值本身。
变量值是在定义时确定的,与后续的内部上下文无关。
如果需要根据不同的上下文环境计算不同的值,应该使用度量值而不是变量,因为度量值会根据当前的上下文环境重新计算其值。
实列:
比如有一张表salse,存在金额、大区、姓名、性别、时间等列a=calculate(sum([金额]),[时间]<date(2024,6,14)),
b=var bb=calculate(a,[大区]="华南")
return b
在DAX中,当定义一个度量值(measure)或计算列(calculated column),并且这个度量值或计算列中嵌套了其他计算或度量值时,嵌套的计算会受到外部筛选上下文(filter context)的影响,包括切片器、过滤器、行上下文等。
例子:
a = CALCULATE(SUM([金额]), [时间] < DATE(2024, 6, 14))
b = VAR bb = CALCULATE(a, [大区]="华南") RETURN bb
度量值b使用了CALCULATE函数,并嵌套了另一个度量值a。这里的重点是CALCULATE函数会考虑当前的筛选上下文。
如果外部有一个筛选器(比如性别筛选器),这个筛选器会影响所有度量值的计算,除非在度量值的定义中明确地使用ALL、ALLSELECTED、REMOVEFILTERS或其他函数来忽略或修改筛选上下文。
在例子中,b度量值会首先计算a(即2024年6月14日之前的总金额),但在计算b时,由于它包含了[大区]="华南"的筛选条件,并且没有使用任何函数来忽略或修改外部筛选器(如性别筛选器),因此b的计算会同时受到[大区]="华南"和外部性别筛选器的影响。
换句话说,如果外部筛选器设置为某个特定的性别,那么b的计算将只包括那些属于“华南”大区、满足性别筛选条件、且在2024年6月14日之前的金额。
如果希望b的计算不受外部性别筛选器的影响,可以在CALCULATE函数内部使用ALL或ALLSELECTED函数来移除或忽略性别筛选器,例如:
b = VAR bb = CALCULATE(a, [大区]="华南", ALL(salse[性别])) RETURN bb
这样,无论外部性别筛选器如何设置,b的计算都将只受到[大区]="华南"和[时间]<DATE(2024, 6, 14)这两个条件的限制。