跳至正文

迭代计算(下):DAX“迭代计算”最后说明,“是”与“不是”

以喜乐君多年学习数据分析的经验,以及最近几个月DAX计算体系的重建过程来看,迭代概念虽然在某些时刻必要(比如嵌套),但并非必须。它带给初学者的恐惧,超过它所能带来的好处。所以,喜乐君将用其他更加易于理解的概念(比如数据合并、嵌套计算、嵌套子查询等),阐述以往迭代的场景。

承接前面两篇文章,本文将最后一次阐述“迭代”是什么、不是什么,之后就不再提起这个概念。

一、迭代是什么

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 重写全文


了解 喜乐君 的更多信息

订阅后即可通过电子邮件收到最新文章。

《迭代计算(下):DAX“迭代计算”最后说明,“是”与“不是”》有3个想法

  1. Pingback: 迭代计算(中):DAX迭代计算的分类 – 喜乐君

  2. Pingback: 迭代计算(上):迭代、X聚合与详细级别 – 喜乐君

  3. Pingback: 迭代计算(中):DAX迭代计算的分类-喜乐君-敏捷BI布道师

评论已关闭。

了解 喜乐君 的更多信息

立即订阅以继续阅读并访问完整档案。

Continue reading