以喜乐君多年学习数据分析的经验,以及最近几个月DAX计算体系的重建过程来看,迭代概念虽然在某些时刻必要(比如嵌套),但并非必须。它带给初学者的恐惧,超过它所能带来的好处。所以,喜乐君将用其他更加易于理解的概念(比如数据合并、嵌套计算、嵌套子查询等),阐述以往迭代的场景。
- 迭代计算(上):迭代、X聚合与详细级别 2023/1
- 迭代计算(中):DAX迭代计算的分类 2023/2
- 迭代计算(下):DAX“迭代”最后一次说明 2023/3
承接前面两篇文章,本文将最后一次阐述“迭代”是什么、不是什么,之后就不再提起这个概念。
一、迭代是什么
Iteration迭代,是指定数据表的每一行,逐一执行特定计算的过程。为此,包含迭代过程的函数,必然有两个参数:数据表、表达式。数据表指“在哪个数据表范围中迭代”,表达式指“每一行重复性地做什么”。
最常见的两类迭代计算,是SUMX迭代聚合函数和FILTER迭代筛选函数。如下所示:
SUMX ( <Table>, <Expression> )
FILTER (<Table>, <Expression>)

X迭代计算、FIlter筛选的共同特征是包含迭代过程;而其差异也非常明显。
- SUMX迭代聚合函数,实现了从table(表) 到scalar(标量值)的转换,结构上出现了本质变化;
- FILTER迭代筛选,是从table(表)到table(表)的转换,虽然行数有所减少,但是结构上没有本质变化。
换一个通俗(但可能不严谨)的方式说,SUMX是“多行到一行”的聚合计算、抽象转换;FILTER是“多行到多行”的量变、质不变。——当然,这里SUMX的“一行”是相对于每个分组内部而言的,这也是scalar(标量值)的含义。如果单从结果表的角度看,所有的查询都是从table到table的表操作。
可见,迭代是一种计算方式,一种可以被很多函数包含的计算方式。喜乐君不建议把它称之为“函数”。
迭代看似简单,当迭代的table从实体表变成逻辑表,出现了多层嵌套,迭代就会随着复杂化。
二、“迭代”不是什么?
“迭代是计算类型,不是函数类型”,这太抽象了,为此,这里反过来说一下,迭代不是什么,或者说迭代不能和那些词直接对应。
- 迭代不是 函数(前文所述)
- 迭代 不等于 聚合,但所有聚合都是迭代计算。
- 迭代不对应“计算列”
1)
既然SUMX和FILTER都是迭代器(iterator),而前者是聚合,后者不是聚合,可见“聚合”只是迭代的一类场景。
因此,聚合不是迭代的唯一性特征。
不过,反过来说,所有的聚合都是迭代计算。
DAX中的SUM、AVERAGE、MAX,都会被转换为SUMX、AVERAGEX、MAXX等X函数,初学者不建议使用SUM函数,而建议一律使用SUMX的全称,帮助理解计算背后的迭代过程。

3、
在DAX中,迭代计算既可以出现在计算列(calculate column)中,也可以出现在度量值(Measure)中。不同阶段的SUMX函数虽然语法、函数完全相同,但是所处环境不同,会得到截然不同的值——这也是context至关重要的原因。
比如,如下的两个DAX表达式,SUMX函数及语法完全相同,”=”和 “:=”表示它们分别属于“计算列”和“度量值”。它们都是包含迭代过程的聚合。
Sales[Sales Amount] = SUMX ( Sales, Sales[Quantity] * Sales[Net Price] )
Sales[Sales Amount] := SUMX ( Sales, Sales[Quantity] * Sales[Net Price] )
因此,迭代不是必然属于“计算列”的,迭代和计算位置无关。
为了区分“计算列”和“度量值”两个计算类型、两个计算阶段,DAX中使用了不同的创建入口、有所差别的,如果是在DAX中完全代码书写,则可以使用DEFINE定义column或者measure。如下:

三、能否用SQL中的简单概念代替迭代?
当然,DAX的迭代最终还是要转化为数据库的查询语言,每一个函数都有对应的SQL实现。
比如SUMX,可以理解为SUM+GROUP BY的SQL函数,FILTER则可以理解为SQL的WHERE或者HAVING子句。
比如,在计算列中完成如下的迭代聚合,相对于在数据表的每一个明细行(逐行)增加了销售额总和:
Sales[Sales Amount] = SUMX ( Sales, Sales[Quantity] * Sales[Net Price] )
由于计算列在明细表中完成,我们可以用如下的SQL查询完成“数据表增加所有销售额总和”计算:
SELECT *
FROM Sales a
JOIN (
SELECT SUM([Quantity] * [Net Price]) as total
FROM Sales) b
由于嵌套查询中只有一个值,因此可以省略ON的匹配条件,可以在SQL中完成类似的查询:

这个是迭代中较为复杂的类型,相比之下,DAX的Filter转化为SQL就相对容易多了。
DAX迭代计算的概念,增加了业务用户使用的难度,同时也为高级应用提供了更多空间,可谓“有得有失”。
喜乐君
Mar 20, 2023 Update 重写全文
Pingback: 迭代计算(中):DAX迭代计算的分类 – 喜乐君
Pingback: 迭代计算(上):迭代、X聚合与详细级别 – 喜乐君