当前位置: 首页 > news >正文

如何在 DAX 中计算多个周期的移动平均线

在 DAX 中计算移动聚合很容易。但是,计算一段时间内的移动平均值时会有一些陷阱。由于其中一些陷阱是定义问题,因此我们必须小心,不要选择错误的方法。让我们看看细节。欢迎来到雲闪世界。

添加图片注释,不超过 140 字(可选)

首先,一些数学知识

计算平均值很容易:将值的总和除以实例数。

虽然值的总和很容易,但实例的数量并不像您想象的那么简单。

例如,我们来看看下表:

图 1 — 数字列表

平均值列的计算很简单:

<值的总和> / <行数> = 534.68 / 10 = 53.47

现在,让我们删除一个值,这会改变图片。

图 2 — 有间隙的数字列表

突然,我有两种计算平均值的方法:

<值的总和> / <值的数量> = 547.23 / 9 = 60.8

或者

<值的总和> / <行数> = 547.23 / 10 = 54.72

第二种方法只是定义不同。 例如,假设第一列是客户 ID,我想计算所有客户的平均销售额或活跃客户的数量等。在这种情况下,第二种计算平均值的方法可能是更好的方法。

现在,让我们将其转换为 DAX。

移动聚合——起点

首先我们来构建移动聚合的典型案例。

我想要获得过去四个月的搬家销售额。

现在,我使用销售额的SUM(),因为验证四个月的结果比计算平均值要容易得多。

 
 

销售移动总和 = VAR MaxDate = MAX( '日期'[日期] ) VAR MinDate = CALCULATE( MIN('日期'[日期]) , DATEADD( '日期'[日期], - 3, MONTH ) ) VAR DateRange = CALCULATETABLE( DATESBETWEEN( '日期'[日期] ,MinDate ,MaxDate ) ) VAR Result = CALCULATE([在线销售总和] ,DateRange ) RETURN 结果

首先,我获取当前筛选上下文(例如当前月份)的最后一个日期

其次,我使用DATEADD()来回移三个月。由于我包括了当前月份,因此我只回移了三个月。

如果我想排除当前月份,我必须采取不同的做法。在这种情况下,我必须获取第一个日期并回溯一天以获取上个月的最后一个日期(或使用EOMONTH(MAX('Date'[Date), -1) )。然后,使用 DATEADD() 回溯四个月)。

第三,我使用DATESBETWEEN()来获取两个变量之间的日期列表。

最后,我将日期列表传递给CALCULATE()以返回最终结果。

结果如下:

添加图片注释,不超过 140 字(可选)

我可以通过删除 DATESBETWEEN() 函数并将两个变量直接传递给 CALCULATE() 来简化测量:

 
 

VAR MaxDate = MAX( '日期'[日期] ) VAR MinDate = CALCULATE( MIN('日期'[日期]) , DATEADD( '日期'[日期], - 1, MONTH ) ) VAR Result = CALCULATE([在线销售额合计] ,'日期'[日期] >= MinDate && '日期'[日期] <= MaxDate ) 返回 结果

结果相同,但使用 DATESBETWEEN() 时性能略好(事实表中有 1700 万行)。

由于多种因素都会影响性能,我鼓励您在数据和用例中尝试这两种变体并检查差异。

让我们做平均值

现在,我终于开始计算平均值了。

我使用与在线销售额总计相同的逻辑,并使用 AVERAGEX() 来计算平均销售额:

 
 

平均在线销售额 = AVERAGEX('在线销售额' ,('在线销售额'[单价] * '在线销售额'[销售数量]) - '在线销售额'[折扣金额] )

接下来,我复制上面的度量来计算销售移动平均线,结果如下:

图 4 — 基本平均值和移动平均值的结果

我可以在这里结束并写下“任务完成”。但是别再说了。

一开始,我提到了计算平均值的不同方法。

因此,我开始编写度量值来测试它们。 我编写了以下度量值,将其用作分母,同时使用了 [在线销售额总和] 和提名人:

  • 统计在线销售量 = COUNTROWS('在线销售量')

  • 客户数量 = DISTINCTCOUNT('在线销售额'[CustomerKey])

  • 在线订单数量 = DISTINCTCOUNT('在线销售额'[SalesOrderNumber])

结果变量的代码如下(以 [Count Online Sales] 为例):

 
 

VAR 结果 = CALCULATE([在线销售总额] / [在线销售数量] ,日期范围 )

我可以想到更多的变体(例如,平均总体客户,甚至那些在这段时间内没有订单的客户)。但我决定就此打住,以免造成混淆。

毫不奇怪,他们每个人都得出了不同的结果:

图 5 — 所有变体的平均值结果

结果之间的差异非常大。

您可能会遇到计算平均值的其他方法。

因此,我强烈建议您明确定义如何计算平均值。否则,您可能会向受众提供意想不到的甚至不正确的结果。

月平均销售额

计算平均值时还有一个差异:按月销售额的平均值。

让我们再次看一下月销售额的结果:

图 6 — 仅月销售额

我想计算四个月的平均月销售额。

例如,在九月份,我想计算六月份、七月份、八月份和九月份的月销售额的平均值:

(275'061'552.33 + 303'302'950.82 + 273'004'268.56 + 262'971'889.59) / 4 = ~278'585'165.3 (~ 因为舍入差异我们可能会得到略有不同的结果)

为了满足这个要求,我必须思考如何去做。

我需要提前计算每个月的销售额。然后只考虑每行所需的四个月。最后,计算这四个值的平均值。

这意味着我必须首先生成一个包含所有月度结果的表格,然后仅使用计算平均值所需的值,这是低效的。然后,Power BI 将为表格中的每一行计算此值以可视化结果。

当我从每行的筛选上下文的角度来看待它时,我可以做得更好。

为什么不仅计算可视化中每行相关的月份的销售总额?

基于这种方法,我写了以下措施:

 
 

按月移动平均值 = // 1. 获取当前筛选上下文的第一个和最后一个日期 VAR MaxDate = MAX( 'Date'[Date] ) VAR MinDate = CALCULATE( MIN('Date'[Date]) , DATEADD( 'Date'[Date], - 3, MONTH ) ) // 2. 生成移动平均值所需的日期范围(四个月) VAR DateRange = CALCULATETABLE( DATESBETWEEN( 'Date'[Date] ,MinDate ,MaxDate ) ) // 3. 生成按步骤 2 生成的日期范围过滤的表格 // 此表仅包含四行 VAR SalesByMonth = CALCULATETABLE( SUMMARIZECOLUMNS( 'Date'[MonthKey] , "#Sales", [Sum Online Sales] ) ,DateRange ) RETURN // 4. 计算平均值步骤 3 中生成的表中的四个值 AVERAGEX(SalesByMonth, [#Sales])

这次,我添加了内嵌注释来解释那里发生的事情。

结果如下:

图 7 — 每月平均结果

我在Excel中检查了结果,它们是正确的。

如果您正在考虑创建一个每月预先计算的表格,请再考虑一下。

您将被迫添加对所有维度的引用,并增加数据的粒度,无论如何您都需要编写此度量来满足受众通过所有维度过滤数据的需求。

该解决方案非常高效,计算结果仅需不到0.4秒。

即使扩大所有月份,结果也不需要更多时间来计算。

顺便说一句,这种方法也适用于计算平均值的平均值。

结论

平均值不等于平均值​​。我想这是很清楚的。

但更重要的是,了解应该计算什么以及如何计算至关重要。

理解为什么必须计算一个数字可以帮助你选择正确的计算逻辑。

当逻辑清晰时,应该定义编写 DAX 代码的方法。记住要从筛选上下文的角度来做。有时,这是违反直觉的,但它有助于开发高效的代码。

我希望你今天学到了一些新东西。

感谢关注雲闪世界。(Aws解决方案架构师vs开发人员&GCP解决方案架构师vs开发人员)

添加图片注释,不超过 140 字(可选)

相关文章:

如何在 DAX 中计算多个周期的移动平均线

在 DAX 中计算移动聚合很容易。但是&#xff0c;计算一段时间内的移动平均值时会有一些陷阱。由于其中一些陷阱是定义问题&#xff0c;因此我们必须小心&#xff0c;不要选择错误的方法。让我们看看细节。欢迎来到雲闪世界。 添加图片注释&#xff0c;不超过 140 字&#xff08…...

微信小程序 图片的上传

错误示范 /*从相册中选择文件 微信小程序*/chooseImage(){wx.chooseMedia({count: 9,mediaType: [image],sourceType: [album],success(res) {wx.request({url:"发送的端口占位符",data:res.tempFiles[0].tempFilePath,method:POST,success(res){//请求成功后应该返…...

软件测试人员发现更多程序bug

软件测试人员发现更多程序bug 1. 理解需求和业务&#xff0c;需求评审时候发现bug 熟悉了产品的业务流程、才能迅速找出软件中存在的一些重要的缺陷&#xff0c;发现的软件缺陷才是有价值的。否则即使你能找到一些软件缺陷&#xff0c;那也是纯软件的缺陷&#xff0c;价值不大…...

Nagle 算法:优化 TCP 网络中小数据包的传输

1. 前言 在网络通信中&#xff0c;TCP&#xff08;传输控制协议&#xff09;是最常用的协议之一&#xff0c;广泛应用于各种网络应用&#xff0c;如网页浏览、文件传输和在线游戏等。然而&#xff0c;随着互联网的普及&#xff0c;小数据包的频繁传输成为一个不容忽视的问题。…...

C#入门教程

目录 1.if分支语句 2.面向对象 3.static简单说明 1.if分支语句 我们的这个C#里面的if语句以及这个if-else语句和C语言里面没有区别&#xff0c;就是打这个输出上面的方式不一样&#xff0c;c#里面使用的是这个console.writeline这个指令&#xff0c;其他的这个判断逻辑都是一…...

【MySQL报错】---Data truncated for column ‘age‘ at row...

目录 一、前言二、问题分析三、解决办法 一、前言 欢迎大家来到权权的博客~欢迎大家对我的博客进行指导&#xff0c;有什么不对的地方&#xff0c;我会及时改进哦~ 博客主页链接点这里–>&#xff1a;权权的博客主页链接 二、问题分析 问题一修改表结构 XXX 为 not n…...

Go基础学习08-并发安全型类型-通道(chan)深入研究

文章目录 chan基础使用和理解通道模型&#xff1a;单通道、双通道双向通道单向通道单向通道的作用 缓冲通道和非缓冲通道数据发送和接收过程缓冲通道非缓冲通道 通道基本特性通道何时触发panicChannel和Select结合使用Select语句和通道的关系Select语句的分支选择规则有那些Sel…...

some 蓝桥杯题

12.反异或01串 - 蓝桥云课 (lanqiao.cn) #include "bits/stdc.h" #define int long long using namespace std; char c[10000000]; char s[10000000]; int cnt,Ans,mr,mid; int maxi; int p[10000000],pre[10000000]; signed main() {ios::sync_with_stdio(0);cin.t…...

[linux 驱动]input输入子系统详解与实战

目录 1 描述 2 结构体 2.1 input_class 2.2 input_dev 2.4 input_event 2.4 input_dev_type 3 input接口 3.1 input_allocate_device 3.2 input_free_device 3.3 input_register_device 3.4 input_unregister_device 3.5 input_event 3.6 input_sync 3.7 input_se…...

2023_Spark_实验十:Centos_Spark Local模式部署

参考这篇博客&#xff1a;【Centos8_配置单节点伪分布式Spark环境】_centos8伪分布式环境搭建-CSDN博客...

pyecharts-快速入门

pyecharts文档&#xff1a;渲染图表 - pyecharts - A Python Echarts Plotting Library built with love. pyecharts-gallery文档&#xff1a;中文简介 - Document (pyecharts.org) 一、快速入门案例 from pyecharts.charts import Barbar Bar() bar.add_xaxis(["衬衫…...

vue3打包疯狂报错

打包的时候报错很多Cannot find name ‘xxx‘ 。 但是npm run dev 是运行正常的。 解决方法&#xff1a;package.json中的vue-tsc --noEmit 删掉就可以了。 例如&#xff1a; 这是原来的 {"scripts": {"dev": "vite","build": &quo…...

STM32 软件触发ADC采集

0.91寸OLED屏幕大小的音频频谱&#xff0c;炫酷&#xff01; STM32另一个很少人知道的的功能——时钟监测 晶振与软件的关系&#xff08;深度理解&#xff09; STM32单片机一种另类的IO初始化方法 ADC是一个十分重要的功能&#xff0c;几乎任何一款单片机都会包含这个功能&a…...

Android SystemUI组件(08)睡眠灭屏 锁屏处理流程

该系列文章总纲链接&#xff1a;专题分纲目录 Android SystemUI组件 本章关键点总结 & 说明&#xff1a; 说明&#xff1a;本章节持续迭代之前章节的思维导图&#xff0c;主要关注左侧上方锁屏分析部分 睡眠灭屏 即可。 Power按键的处理逻辑最终是由PhoneWindowManager来完…...

C# 表达式与运算符

本课要点&#xff1a; 1、表达式的基本概念 2、常用的几种运算符 3、运算符的优先级 4、常见问题 一 表达式 表达式是由运算符和操作数组成的。、-、*和/等都是运算符&#xff0c;操作数包括文本、常量、变量和表达式等。 二 算术运算符 2.1 算术运算符的使用 三 常见错误 …...

SpringBoot--最大连接数和最大并发数

原文网址&#xff1a;SpringBoot--最大连接数和最大并发数-CSDN博客 简介 本文介绍SpringBoot的最大连接数和最大并发数。 配置 SpringBoot默认使用tomcat处理请求。tomcat可以指定连接数、线程数等配置。 server:tomcat:# 请求处理线程都在使用中时&#xff0c;新连接请求…...

CF687D Dividing Kingdom II 题解

Description 给定一个 n n n 个点、 m m m 条边的图&#xff0c;有 q q q 次询问&#xff0c;每次询问一个 [ l , r ] [l,r] [l,r] 的区间&#xff0c;求将 n n n 个点分为两个部分后&#xff0c;编号在 [ l , r ] [l,r] [l,r] 内的边中&#xff0c;两端点属于同一部分的…...

高空抛物AI检测算法:精准防控,技术革新守护城市安全

近年来&#xff0c;随着城市化进程的加速&#xff0c;高楼大厦如雨后春笋般涌现&#xff0c;但随之而来的高空抛物问题却成为城市管理的一大难题。高空抛物不仅严重威胁行人的安全&#xff0c;还可能引发法律纠纷和社会问题。为了有效预防和减少高空抛物事件的发生&#xff0c;…...

html+css+js实现Collapse 折叠面板

实现效果&#xff1a; HTML部分 <div class"collapse"><ul><li><div class"header"><h4>一致性 Consistency</h4><span class"iconfont icon-jiantou"></span></div><div class"…...

RM服务器研究(一)

客户端默认端口是10100&#xff1a; MultiPort.dll BOOL sub_10001070() { UINT v0; // esi BOOL result; // eax CHAR KeyName; // [espCh] [ebp-10Ch] DWORD flOldProtect; // [esp10h] [ebp-108h] CHAR Buffer; // [esp14h] [ebp-104h] char v5; // [esp15h] [e…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件&#xff0c;我的文件路径是/etc/mysql/my.cnf&#xff0c;有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...