不问花开几许,只愿浅笑安然 除了求和,另一个日常工作中最常用到的聚合方式应该是计数了。DAX提供了一系列关于计数的函数。他们可以帮助我们计算表中有多少行或者某个值出现了多少次。...DAX中包含的计数函数有: COUNT()函数,对列中值的数量进行计数,除了布尔型; COUNTA函数,对列中值的数量进行计数,包含布尔型; COUNTBLANK()函数,返回列中空单元格的计数; COUNTROWS...一、计数与不重复计数 假设我们想看看不同产品类别中有多少种产品,并且想知道这些产品是不是多卖出去过(有交易记录)。我们就可以使用以上函数实现。...观察办公用品中的结果可知:办公用品分类一共有8中产品,但实际有销售出去的仅有2中种,其他的产品都未出售过,需要进一步了解原因。 两个度量值使用的列是来自不同的表的,虽然他们都代表了产品名称。...该函数对于列中的同一个值仅计算一次。 二、对行计数 COUNTROWS()函数与其他计数函数不同点之一就是它接受的参数是表。而其他计数函数接受的参数都是列。
注意 后面你会了解到,嵌套函数的执行顺序可能会令你感到困惑,因为CALCULATE和CALCULATETABLE函数的计算顺序与FILTER函数不同。在下面的章节中,你将学习到FILTER函数。...一条DAX查询语句是一个返回表的DAX表达式,与EVALUATE语句一起使用。...DAX查询的强大之处在于其可以使用众多的DAX表函数。在下一节中,你将学习如何通过使用和组合不同的表函数来创建高级计算。...VALUES函数返回在当前筛选器中计算的列的不同值。如果在计算列或计算表中使用VALUES或DISTINCT函数,则它们与ALL函数的行为相同,因为没有生效的筛选器。...现在的重点是理解为什么同一种行为会出现 VALUES和DISTINCT两个变体。其区别在于它们考虑表中存在空行的方式。首先,我们需要理解,如果没有显式地创建空行,为什么表中会有空行存在?
(一) 和Excel相同用法函数 这里就不多做介绍。主要是介绍差异及DAX特有函数。 (二) 和Excel有差异函数 1....差异情况 差异原因 Excel函数 Dax函数 函数名称 DateDif DateDiff 计算方式 根据实际时间 只根据计算条件 2....填写1-12的月份数字 往前推或者往后延做成年份日期表 B) 返回 表——单列日期表 C) 注意事项 如果数据表中没有日期列则会出错 参数为正数则表示会计年份从1月往后算,负数则是从1月往前算。...D) 作用 自动生成会计日期列 E) 案例 自动生成时间日历表 CALENDARAUTO() 如果数据模型的日期范围是2018/5/1—2019/6/30,则生成的日期表范围为2018/1/1—2019.../12/31 生成会计年度为每年4月 CALENDARAUTO(3) 如果数据模型的日期范围为2018/1/1—2018/12/31,则生成的日期表范围为2017/4/1—2019/3/31。
很多业务背景的伙伴进入 DAX 世界后,第一个拦路虎就是 EARLIER。 因为这是我们业务人员平时不用的思维逻辑:迭代。 迭代,是区分文科与理科;业务与 IT 的标志性思维逻辑。...理解 DAX 中的 SUM 在 DAX 中,SUM 的用法如下: [Sales] := SUM( Order[Amount] ) 它完全等价于: [Sales] := SUMX( Order , Order...从逻辑上来讲,SUMX 有两个重要动作: 在遍历的元素的时候提取元素 最后在遍历完成时全部加起来 注意:实际 DAX 引擎的物理执行可能与此不同,但逻辑上可以这么理解。...那么,函数 EARLIER 就起到了跨层穿越的效果。...而实际的结果是: 在这个场景中,SUMX ( B , [B] * [A] ) 与 SUMX ( B , [B] * EARLIER( [A] ) ) 完全一致。
有很多小伙伴常常问到含有递归特性的 Power BI DAX 计算问题,这在 DAX 中应该如何解呢? 本文来阐述【比例型】的解决方案。...问题场景 已知每年的预期增长率如下: 以及每年的销售额,如下: 分别求各年的预计销售额。 问题分析 对于预期增长率表,其含义为: 当前年份相对前一年份的预期增长率。...DAX 的递归限制 DAX 并不提供对递归计算的天然支持,导致一些问题无法自然得解。Excel 中可以轻松解决的问题,在 DAX 中变得很复杂。...在 DAX 中,却无法直接引用上一行元素,导致无法实现递归计算。 递归的特殊形态 递归存在一些特殊形态,通过数学运算的等价性,可以在某些场景中给出结果。...该递归化解的方法,可以解决一大票常见的 DAX 递归问题,但并不能解决任意递归问题。本例的特点在于第 n 项与第 n-1 项是一种单纯的比例关系,对于复杂的函数运算关系,则很可能无法求解。
基本思想 从微观的角度,对于某种产品,如:《BI 真经》有其定价,该定价与市场的客户心理预期有一种隐含的关系,他们通常表现为: 如果价格普遍高于心理预期,销量下降; 如果价格普遍低于心理预期,销量上升。...如何找到产品服务与客户心理预期的最佳匹配点是实现理论最大营收的关键所在。...那么, 如果 A > B,则降低价格提升销量的策略更好; 如果 A < B,则上调价格业绩提升的策略更好; 同时,价格调整与销量变化的平衡点可以在这个过程中拿捏。...尽管如此,但同一产品可能存在不同的打折方式,而导致在不同的交易中,产品表现出来的价格不同。...更多解释 由于产品 SKU 是众多的,在 DAX 数据模型中,可以借助强大的计算能力,对每个 SKU 独立计算再累加。因此,这里的 SUMX 函数就起到了重要作用。
SUMX 函数 DAX设计了一系列后缀为X的函数,SUMX,AVERAGEX,MAXX,MINX...它们与Filter和Earlier一样,都属于行上下文函数。...3.SUMX记住了每一行返回的值,最后把所有的值加总起来求和。 可以想想,如果没有SUMX这样的行上下文函数,我们求销售额的方法就要绕个弯路。...有点像在Excel中的操作,新建一列[乘积]=[价格]*[数量],再建一个度量值[销售额]=SUM([乘积])。 ? 这个方法可以达到与SUMX同样的效果,然而我一般不建议大家这样去做。为什么呢?...这是一个度量值方法与计算列方法的对比问题。在第一次介绍度量值与计算列时我们提到过它们的区别。 度量值只有放到图表中才会执行计算,而计算列在创建后就会把整列数据存储在文件中,增大文件的容量。...除了在度量值和计算列两个方法中做出选择,在写一个度量值时,因为DAX提供的公式很灵活,达到同一个目的方法也有很多。很多时候,不管白猫黑猫,能捉老鼠就是好猫。 ?
Js中的函数声明是指下面的形式: function functionName(){ } 这样的方式来声明一个函数,而函数表达式则是类似表达式那样来声明一个函数,如: var functionName...= function(){ } 可能很多朋友在看到这两一种写法时会产生疑惑,这两种写法差不多,在应用中貌似也都是可行的,那他们有什么差别呢? ...事实上,js的解析器对函数声明与函数表达式并不是一视同仁地对待的。...对于函数声明,js解析器会优先读取,确保在所有代码执行之前声明已经被解析,而函数表达式,如同定义其它基本类型的变量一样,只在执行到某一句时也会对其进行解析,所以在实际中,它们还是会有差异的,具体表现在,...当使用函数声明的形式来定义函数时,可将调用语句写在函数声明之前,而后者,这样做的话会报错。
公式栏里,无论是第一种直接引用列,还是第二种表名列名绑定一起,都会出现错误提示 说明在度量值里,这种方式是不允许的 为什么会这样?...因为度量值不会自动创建“行上下文”,而计算列可以,所以在语法源头上就出错了 (三)度量值里使用聚合类迭代函数(SUMX) 从语法上来说,度量值就是由DAX函数构成的,迭代函数也是DAX的一种,自然更没障碍...SUMX函数的第一参数是“在线销售表”,系统先确定该表的上下文环境 1)筛选上下文:时间切片器与大小类筛选 2)行上下文:空(此时还未执行SUMX,因此还未生成行上下文) 2....SUMX为迭代函数,对上一步确定下来的表,创建一个新的“行上下文”(牢记:“行上下文”仅作用于数据模型里的原表,而非可视化表元素) 3....根据不同的可视化元素,度量值(利润)做出相应汇总 至此,我们再次认识到 ★行上下文”只告诉DAX该使用数据模型的哪一行,任何时候都无法筛选模型,也无法覆盖外层的筛选上下文 ★“筛选上下文”只能依靠报表视图各类筛选器的叠加组合来产生
[1240] 之前的一期,白茶曾经分享过一次关于迭代循环的文章《迭代循环丨SUMX函数》,本期咱来深入聊聊这个问题。 聚合器: 在大部分数据模型中,几乎都需要我们对数据进行聚合类的操作。...DAX中提供了很多聚合类的函数,最常用、频率最高的是SUM函数。比如说这种: 销售额 = SUM ('表'[销售] ) 这就给很多人造成了误解,聚合器就是SUM函数,这是不对的。...还有很多其他的,比如说:AVERAGE求平均,MIN求最小值,MAX求最大值。这些函数本质上都是聚合器,只不过是聚合之后返回的结果不同罢了。更确切的说,聚合,这个定义是一种思维方式。...迭代器: 一些特定的函数可以对整个表进行聚合,或者根据行上下文一行一行的去筛选,这类函数就属于迭代器。他们的工作方式针对的不是一个列,而是一个表。...MIN与MAX: 这里单独提一下这俩函数,其他的聚合器基本上都是针对数值生效的,但是MIN和MAX对于文本也是生效的。
但我们可以得到这样的共识,逻辑框架,这涉及两个内容: 数据结构 - 数据以什么形式摆放 计算方法 - 如何基于数据摆放的结构进行计算 数据结构和算法,在大学课程中,有两本厚厚的书与之对应,例如: ?...在任何关于 DAX 的资料里,只会告诉你 DAX 中存在两个上下文:筛选上下文和行上下文,但没有任何资料讲它们为什么要存在。就好像是上帝,说要有光,于是就有了光,那为什么要有光呢?...感受 DAX 中的算法与数据结构 由于 DAX 的设计初衷是给商业分析师的,也就是业务人员,所以,我们不会把大家搞成程序员,但这丝毫不影响我们去理解思想。...我们后续会计算展示不同数据结构的使用,但这些仅仅是《Thinking in DAX》的一个部分哦。 计算逻辑 这是本文的重点内容了。...在上面的每一步的反复实践中,您会慢慢地: 在每一步的最终细节,使用 DAX 函数落地,具体可以参考 BI 佐罗的《DAX 36 个核心函数》。
初识行上下文 在介绍两种上下文过程中,我会尽量列举它们在计算列和度量值中的不同表现,来增强大家的感性认识。...错就错在,我们把EXCEL的思维方式套在了DAX身上 在EXCEL里,对于列的计算,我们都是在首行单元格输入公式,通过下拉填充,得出全列结果。每个单元格的公式,除了运算符号不变,单元格引用都不同。...用迭代器 迭代器其实就是迭代函数,末尾带字母X的函数都自备迭代功能,诸如SUMX,AVERAGEX,COUNTX,MAXX,MINX等 ?...上图中,SUMX函数作为迭代器,将创建了一个“行上下文”,并对SUMX第一个参数“销售表”进行迭代,在行上下文中,执行SUMX的第二个参数(单价乘销量的表达式)。...因此,在迭代过程中,每行表达式都明确知道自己应该用哪一行的销量和单价来运算 ? 再重复一次: 为什么同样的表达式,在计算列里就能正确执行,而到了度量值里却不行?
DAX 作为一门动态数据分析语言,与 Excel 函数、SQL 查询 和 Power Query 脚本有着根本不同的原因就在于上下文的概念。...有时容易被疏忽的一点是,筛选器参数中未涉及的列会继续保留其筛选器(如果存在)。由于无法完全控制原始上下文的外观,因此在查看度量值可能用于的不同方案时应小心。您可能需要移除比最初预期的更多的筛选器。...显然,使用 CALCULATE 计算的两个度量值返回了不同的结果。为什么会有这种差异呢?...此处要使用的 DAX 函数是 SUMX,代码如下。...若要清楚知晓此类表达式到底做了什么,理解 DAX 上下文在表函数中的工作方式非常重要。让我们在一个完整的度量值公式中使用 GENERATE 来说明这一点,代码如下。
现给出结论:在DAX中不存在真正的SUM。...很多人一定懵了,DAX 在被设计的时候被刻意地与Excel函数的用法做了贴近,而导致PowerBI的运算可以很快入门,但很快就会遇到一个普遍现象:DAX的计算结果和你期望的结果完全不同,而你无法解释为什么...真正的原因在于:在DAX中,是不存在SUM的,任何的SUM在计算时都会转化成SUMX。...回到这个问题来看,这里确实不会忽略行上下文,而是将SUM转换成了SUMX,并进入SUMX进行计算,而SUMX将创建新的迭代过程,在表中逐行迭代,进而得到了整列的聚合结果。...但我也充分知道他们和我一样是知道SUM会被转换为SUMX的,他们这样描述,我猜想是要避免告诉你这么多底层的内容,就会增加学习难度。 吾爱吾师,吾更爱真理。并不是一个口号,它体现在你所有的学习和工作中。
首先,请死记:筛选和迭代是数据分析过程中的两大重要特性。 筛选,帮助我们从宏观到微观; 迭代,帮助我们具体考察每一个微观元素。 这也是 DAX 中,筛选上下文和行上下文的设计学来由。...对于一个表的迭代,由于表是行的集合,每一行都表示同类事物的不同个体,如:不同的每一笔订单。很自然地可以将对表的迭代理解为对表中的行集合的迭代。...) 如果黄色箭头指向元素的KPI大于当前绿色箭头指向元素的KPI则保留 内圈迭代完成,剩下了 vItems 是在迭代中胜出的元素 求这些 vItems 的 KPI 与整体 KPI 的比值 %。...因此,在 DAX 中,所有带有需要处理集合中元素语义的功能都是干坏事,都内部包裹了一个看不见的迭代器。 总结 迭代,是很自然的。...当你的业务逻辑涉及到对一堆元素(如:表行)进行遍历并在每一步都做点坏事的时候,一定会自然而然地用到某些函数,这些函数自然而然的都包裹了一个看不见的迭代器。
这里涉及一个关键函数是:SUMX。 套路:用 SUMX 按分组对 [KPI.Row] 进行包裹。即可。 下面从具体的案例来说明这个套路。...【情况3】多列总计,不同表,同桥 这种情况更加复杂,多列来自不同的表,当然,有个特点是他们有一个共同的桥。 什么是桥表? 在多个一对多关系中,作为共享的多端的表,就是桥表。...度量值: Topic.Value.Display.FromMultiTable.ButSameBirdge = // 多列总计,多列来自不同的表,但共享一个桥表 // 什么是桥表,在多个一对多关系中,作为共享的多端的表...与桥表连接的表的列都可以用作后续参数,则这个 DAX 表达式会返回合理的多列分组。...,不同表,有桥 可以应对多列分组,不同表,无桥 DAX 公式异常简单好记 同时满足上述 9 大特性,因此,我们说这是总计行问题的终极解决方案。
对于左右两个图表,它们的规律是: 左图:在分组区域内,按照与当前元素的KPI从小到大,积累求和; 右图:在分组区域内,按照与当前元素的名称从小到大,积累求和。...这便是对 DAX 计算的反思。...微软 PowerBI 产品组正在面临一个非常尴尬的抉择问题: 1、若 PowerBI 提供原生的视图层计算功能,如:一个新的函数集合,但不属于 DAX,那么,这将使得 PowerBI 除了有 Power...Query 的 M,以及数据建模 DAX,又将出现一个视图计算的新函数库,导致 PowerBI 会变得更加难以理解,这是不希望发生的。...2、若 PowerBI 将视图层计算功能融入到 DAX 中,将导致作为纯模型层计算的函数库 DAX 掺杂了其他内容而使得 DAX 不再纯粹,这也是不希望发生的。
DAX 中的表有两类:基表(base table)以及用作临时用途的表(table)。参考:DAX 中的表。 我们发现两个重要问题,这也是很多小伙伴提问的。这里来讲清楚。...正确的再次聚合 那如果要实现再次聚合怎么做呢?这里给出两个方法,通过对比来感受不同方法的作用。...这里的筛选的意义在于: 选择与当前行范围一致的数据子集。 那么,从这点来看,显然迭代整个表是有些浪费的。 这里可以用 VAR 来代替 EARLIER 使得整个计算更容易理解。...而这个场景中,几乎就是 GROUPBY 的最佳使用场景,请看看它解决了什么问题,它解决了直接从内存表中获得与行上下文中内容匹配的集合的作用,这个作用是筛选上下文无法作用到的地方,而它的功效恰恰就干了这个事情...《DAX 权威指南》对比了该函数与其他函数的区别并给出了一个类似例子来说明 GROUPBY 在上述场景下的功效。而本文则给出该使用 GROUPBY 的业务运算定式逻辑。
当时的白茶哑口无言,可是越深入学习PowerBI,越能知道它的用途是多么强大,可能DAX很多人都在诟病它,但是存在就是有价值,就是合理的。 开始今天的话题,IF的灵活运用。...假如,我有一份不同客户的销售清单,我想知道这些客户在我这消费购买了什么。想以此来判断哪些客户是普通客户,哪些客户是优质客户,哪些是潜在客户。 示例如图: (小伙伴请忽略单价,白茶图省事,瞎填的。)...涉及到的函数有VALUES,CONCATENATES。 之前的文章有提及到VALUES,它的作用是返回表格中的唯一值,这里就不赘述了。...我们来看看CONCATENATES: DAX= CONCATENATEX(, , [delimiter]) Table:要对其进行计算的表,可以是直接的表,也可以是函数表...话不多说,编写代码: 购买物品 = CONCATENATEX (VALUES( Sheet1[物品类型] ),'Sheet1'[物品类型],",") 结果如图: 会发现,符合我们预期的效果。
在学习 Power BI 的 DAX 过程中,不免会遇到一些问题和你想的不一致。例如以下问题来自伙伴在实际业务中涉及到的公式,我们来拆解并帮助大家梳理对于 DAX 的理解。...订单 '[数量] ) > 20000 ) 中的 ALL (' 客户 ') 会得到所有客户,并进行迭代,但由于 SUMX 中的第一个参数'订单' 所处于的筛选上下文正是矩阵中当前行,注意:不是 FILTER...但对于应用开发者,应该使用 C#,Java,Python 等面向应用的设计语言,而屏蔽底层的复杂性。 DAX 是一门非常有特点的函数。...如果你感觉你的理解和上述三点不一致,那么,不要说我,以上 3 点来自官方原话,要喷就直接去官方喷吧。那为什么你的感受完全不同的,很简单,因为你没有学习《BI 真经》。...如图: 相关文章 彻底理解 PowerBI DAX 函数 EARLIER 【DAX 系列】高清图解迭代原理并弃用 EARLIER 从SUM让人看看PowerBI DAX的坑爹之深
领取专属 10元无门槛券
手把手带您无忧上云