[知识体系] 聚合函数

  [复制链接]
查看125814 | 回复127 | 2021-2-21 19:30:47 | 显示全部楼层 |阅读模式
认识聚合函数

几乎所有数据模型都需要对聚合数据进行操作。DAX 提供了一组函数,它们可以聚合表中某一列的值,并返回一个值。我们称这组函数为聚合函数。例如,以下度量值用于计算销售表 SalesAmount 列中所有数字的总和:
  1. Sales:= SUM ( Sales[SalesAmount] )
复制代码

如果在计算列中使用这个表达式,它将聚合表的所有行;如果将其用在度量值中,它将综合考虑所在透视表的切片器、行、列筛选器和其他筛选条件,并在这些条件筛选后的行中计值。常用的聚合函数(SUMAVERAGEMINMAX、STDEV 和 VAR)只对数值或日期进行操作。
聚合函数是最基础也是最常用的函数,因为度量值必须返回标量结果(数值),这意味着即使计算过程中使用表作为筛选条件,最终也必须通过聚合函数输出一个标量。


统计文本的聚合函数

与 Excel 类似,DAX 为聚合函数提供了另一种可选语法,可以对包含数值和非数值的列进行计算,比如文本列。该语法将后缀 A 添加到函数的名称中,以获得与 Excel 相同的名称和行为。但是,这些函数只对包含真/假值的列有用,因为 TRUE 被计算为 1,FALSE 为 0,而文本列始终被视为 0。因此,无论列的内容是什么,如果在文本列上使用 MAXA,结果总是 0。此外,DAX 在执行聚合时从不考虑空单元格。


即使这些函数可以在不返回错误的非数字列上使用,它们的结果通常也没有用,因为文本列无法被自动转换为数值。这些函数是 AVERAGEACOUNTAMINAMAXA


尽管这些统计函数的名称相同,但是它们在 DAX 和 Excel 中使用的方式存在差异,因为在 DAX 中,列具有类型并且其类型确定了聚合函数的行为。Excel 以单元格为单位处理数据类型,而 DAX 以列为单位处理数据类型。DAX 以表格形式处理数据, 每列都具有规范定义的类型, 而 Excel 公式则适用于异构单元格值, 没有明确定义的类型。如果 Power Pivot 中的列具有数字类型,那么所有值只能是数字或空单元格。如果列是文本类型,那么这些函数(COUNTA 除外)的值总是 0,即使文本可以转换为数字。而在 Excel 中,值是按逐个单元格计算的。综上所述,这些 DAX 函数对于文本列不是很有用。

特殊用法

MINMAX 还有另一个功能:如果使用两个参数,它们将返回两个参数的最小值或最大值。因此,MIN(1,2)将返回 1,MAX(1,2)将返回 2。这个功能新增于 2015 年,在计算复杂表达式的最小值或最大值时非常有用,因为它避免了在 IF 语句中多次编写相同的表达式。

计数类型

前面学习的函数对于计算聚合值非常有用。但有时候,你对聚合值不感兴趣,而只对计数感兴趣。因此,DAX 提供了一组有用的函数,可用于对行或值计数:


  • COUNT 仅在数字列上运行
  • COUNTA 在任何类型的列上运行
  • COUNTBLANK 返回列中空单元格的数量
  • COUNTROWS 返回表中的行数
  • DISTINCTCOUNT 返回列中非重复值的个数


COUNTA 是后缀为 A 的函数组中一个有趣的函数,因为它返回列中非空行的数量,可以在任何类型的列上工作。如果要计算列中包含空值的数量,可以使用 COUNTBLANK 函数。最后,如果要计算表的行数,可以使用 COUNTROWS 函数。注意,COUNTROWS 需要一个表作为参数,而不是列。


对于任何表的任何列,COUNTA(table[column]) + COUNTBLANK(table[column])的结果总是等于 COUNTROWS (table)


最后一个函数 DISTINCTCOUNT 非常有用,因为它完全按照名字的含义运行:统计列的不同值的数量,用列作为惟一的参数。DISTINCTCOUNT 将空白值视作可能的值之一。
DISTINCTCOUNT 是在 2012 版本的 DAX 中引入的函数。早期版本的 DAX 不包括非重复计数,若要计算列的不同值的数目,必须使用 COUNTROWS ( DISTINCT ( table[column] )。这两种写法的原理相同,尽管 DISTINCTCOUNT 更易于阅读,只需要调用一个函数,但其本质是 COUNTROWS ( DISTINCT ( table[column] )的语法糖


聚合表达式的聚合函数

到目前为止我们学习的所有聚合函数都是针对列的(COUNTROWS 除外,它适用于表)。因此,它们只能聚合单列的值。有一些聚合函数可以聚合一个表达式,而不是单个列。当你想使用相关表的不同列进行计算时,这组函数非常有用。例如,如果销售表包含所有销售交易记录,而与销售表相关的产品表包含所有产品信息,包括成本,你可以通过使用以下表达式定义的度量值来计算销售交易的内部总成本:
  1. Cost:= SUMX ( Sales, Sales[Quantity] * RELATED ( Product[StandardCost] ) )
复制代码

此度量值计算销售表中每一行的销售数量(从销售表)和销售产品的标准成本(从产品表相关行)的乘积。最后,它返回所有计算结果的总和。


以 X 后缀结尾的所有聚合函数都有这样的行为:它们在表(第一参数)的每行的执行表达式 (第二参数), 最后由相应的聚合函数(SUM, MIN, MAX 和 COUNT) 返回应用于表达式的结果。


在理解迭代函数一文中,你将进一步了解这种行为,届时,我们将引入计值上下文的概念。X-后缀函数有 SUMXAVERAGEXPRODUCTXCOUNTXCOUNTAXCONCATENATEXMINXMAXX。还有一些迭代器没有 X 后缀,比如 FILTERADDCOLUMNS。稍后将详细介绍。
如果按聚合的对象分类,我们可以把聚合函数划分为三种不同类型:聚合列、聚合表达式和聚合表
深入理解聚合函数


聚合函数的行为在简单场景下非常直观,与 Excel 函数类似,不需要做额外说明。但是在一些特定的上下文环境中,它的行为可能有一些古怪,很多新手在刚刚接触 DAX 的时候会在这里遇到困难。其实,一旦理解了聚合函数的本质,并且积累了对上下文的认识,对这个问题的理解就会逐渐清晰。

上文提到过,如果在计算列中使用聚合函数,它将聚合表的所有行,这是因为聚合函数忽略行上下文,只考虑筛选上下文,所以除非发生行上下文转换,否则聚合函数始终对整列执行聚合。当你理解了聚合函数在计算列中的计值流之后,让我们加入一点点变化,下面这个度量值可能让很多 DAX 初学者感到匪夷所思:
  1. 截至当前日期的累计销售额 =
  2. CALCULATE (
  3.     SUM ( SALES[Sales amount] ),
  4.     FILTER (
  5.         ALL ( Date ),
  6.         Date[date]
  7.             <= MAX ( Date[date] )
  8.     )
  9. )
复制代码

我们不讨论这个公式的其他部分,只把精力集中在高亮的第七行,如果你认为这里的 MAX 返回的是当前行上下文的日期,那么 FILTER 的第二参数在每行计值时得到的结果都是 True,FILTER 将返回整个日期表,这显示是错误的。实际上,MAX 作为一个聚合函数,在这里仍然遵循忽略行上下文,只考虑筛选上下文的规律。后面在介绍 CALCULATE 的时候你会了解到,FILTER 表达式在原始筛选上下文条件下计值,所以 MAX ( Date[date] )的筛选上下文来自外部筛选器,也就是报表筛选条件约束下的日期,MAX 在这个日期范围中取最大值用于逐行判断。
聚合函数的本质
聚合函数忽略行上下文,只考虑筛选上下文的行为似乎过于抽象,但当你了解聚合函数的本质后,这种行为就会变的非常直观。因为任何一个聚合函数都是下面这种写法的简化,比如 SUM(Table[Column]) 的本质是
  1. SUMX( Table, Table[Column] )
复制代码

请仔细思考上面的写法,对于这个公式而言,SUMX 的第一参数会被来自外部的筛选上下文所影响,而行上下文不会对它产生任何作用。其他聚合函数也具有类似的等价转换,实际上聚合函数是一类特殊的 Aggregation &#8211; X 函数的简化形式。这也解释了本小节开始时提出的疑问。
回复

使用道具 举报

东莞高步康 | 2021-4-24 17:46:42 来自手机 | 显示全部楼层
呵呵,明白了
回复

使用道具 举报

popupp | 2021-6-1 13:00:41 | 显示全部楼层
前排,哇咔咔
回复

使用道具 举报

hsy001 | 2021-6-13 08:37:36 | 显示全部楼层
纯粹路过,没任何兴趣,仅仅是看在老用户份上回复一下
回复

使用道具 举报

the_hope | 2021-6-18 07:30:18 来自手机 | 显示全部楼层
支持楼主,用户楼主,楼主英明呀!!!
回复

使用道具 举报

beer | 2021-9-4 07:31:58 | 显示全部楼层
鼎力支持!!
回复

使用道具 举报

金竹坑 | 2021-9-7 06:52:39 来自手机 | 显示全部楼层
看起来好像不错的样子
回复

使用道具 举报

dgzxpx | 2021-10-1 13:20:18 | 显示全部楼层
支持,一直很喜欢老师的课程
回复

使用道具 举报

lc3662018 | 2021-10-17 17:01:39 来自手机 | 显示全部楼层
云发教育是我遇到最好的机构,和其他机构有本质区别
回复

使用道具 举报

wangzig | 2021-10-18 23:41:39 | 显示全部楼层
不错 支持一个了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则