东哥陪你学DAX——上下文系列小讲堂(二)

初识行上下文

在介绍两种上下文过程中,我会尽量列举它们在计算列和度量值中的不同表现,来增强大家的感性认识。(本系列所用示例,来自微软官方样本数据库AdventureWorks)

“行上下文”是怎么来的?

1. 创建计算列
2. 使用迭代器(以X结尾的函数)

东哥陪你学DAX——上下文系列小讲堂(二)_第1张图片
014.png

先来看计算列

东哥陪你学DAX——上下文系列小讲堂(二)_第2张图片
010.png

上表中,“利润”和“销售额”均为计算列

销售额 = [销量] * [单价]

利润 = [销量] * ([单价] – [成本])

对初学者来说,上述公式能得到正确结果,是天经地义,再正常不过了。因为EXCEL里的列计算就是这样,加减乘除结果怎么可能会错

上面这句话,只说对了一半
错在哪里?错就错在,我们把EXCEL的思维方式套在了DAX身上

在EXCEL里,对于列的计算,我们都是在首行单元格输入公式,通过下拉填充,得出全列结果。每个单元格的公式,除了运算符号不变,单元格引用都不同。该列的每一行,只使用当前行单元格来参与运算

东哥陪你学DAX——上下文系列小讲堂(二)_第3张图片
011.png
东哥陪你学DAX——上下文系列小讲堂(二)_第4张图片
012.png

而DAX是以列运算为主,整列就一个公式,怎样确保参与运算的都是当前行,而不会出现第三行销量第五行单价第八行成本算到一块儿去?

之所以整列计算结果都正确,恰恰因为“行上下文”的存在并起了关键作用

只要创建计算列,就会自动创建行上下文,无需手工干预。行上下文就是如来手掌,计算列的运算无论如何也跳不出去

就拿上面两个公式来说,计算列一旦创建,DAX立刻就从第一行开始迭代,同时也创建了一个包含当前行的行上下文并开始计算。计算动作发生之前,行上下文已锁定当前行,因此整列计算才不会出错

那要如何通过度量值来建立“行上下文”?

迭代器

迭代器其实就是迭代函数,末尾带字母X的函数都自备迭代功能,诸如SUMX,AVERAGEX,COUNTX,MAXX,MINX等

东哥陪你学DAX——上下文系列小讲堂(二)_第5张图片
017.png

上图中,SUMX函数作为迭代器,将创建了一个“行上下文”,并对SUMX第一个参数“销售表”进行迭代,在行上下文中,执行SUMX的第二个参数(单价乘销量的表达式)。因此,在迭代过程中,每行表达式都明确知道自己应该用哪一行的销量和单价来运算

东哥陪你学DAX——上下文系列小讲堂(二)_第6张图片
033.png

再重复一次:
为什么同样的表达式,在计算列里就能正确执行,而到了度量值里却不行?

因为计算列会自动创建行上下文,而度量值却不会

如果想在度量值内逐行计算该表达式,必须通过迭代函数来人为创建行上下文

还有一点需要注意,“行上下文”里的“行”,是针对数据模型里的表而言(后面会提到虚拟表的概念,虚拟表中也可以使用行上下文),而不是可视化元素下的表格和矩阵。前者是模型原表,后者是聚合后再被筛选过的数据容器。DAX无法直接引用后者的行或列,避免矫枉过正

东哥陪你学DAX——上下文系列小讲堂(二)_第7张图片
044.png

行上下文入门小结:

  1. 计算列和迭代函数都可以创建行上下文
  2. 执行计算的行没有储存在公式内部,而是由行上下文定义
  3. 行上下文只包含一行(基于行号,永远不会重复),并且在被创建时自动定义
  4. 行上下文只用来决定引用目标列的哪个值(即确定计算发生在哪一行)
  5. 表格的列并没有某个确定的值,列在表格每一行都有一个值,如果你想让列取得某个值,需要确定这个值所在的行,而确定行的唯一方式是使用行上下文
  6. 要使用“行上下文”,要么通过计算列、要么通过迭代函数
018.png
image

(未完待续)

你可能感兴趣的:(东哥陪你学DAX——上下文系列小讲堂(二))