DAX 的世界,其实,也非常混乱。为什么用了一个也字呢?读完本文,你就懂了。
正如很多人说自己熟悉 Excel ,但问一个基础问题时:
在 Excel 中,到底什么是表?
在实际测试中,99% 的人是混淆的。(这里不再讨论,可以翻看此前文章)
Excel 中有由单元格区域构成的表结构;Excel 中有创建表得到的工作表表格;Excel 中有数据模型中的数据模型表;Excel 中有透视表;以上 4 种表是完全不同的概念。而这些基础需要伙伴们注意。
那么,在 DAX 中,到底什么是表?
关于这个问题,一样混乱不堪,99% 的人是混淆的。
不信,我们就来慢慢帮大家理清这个问题,看看你以为的基础是不是那么基础。
为了描述事物,需要概念。而概念往往可以肆意编造。在 DAX 中,大概会看到与表相关的概念如下:
表,基础表,基表,表引用,列引用,临时表,表表达式,桥表,计算表,维度表,事实表,中间表,一维表,二维表,汇总表,矩阵表等等。
作为学习者,往往以为自己知道啥是啥,其实只是徒增了概念而已。而这些概念很多是非本质的,是无根的。
对于严谨的教程而言,这是严重的问题。
到底应该用什么概念呢?
1、自行编造法
这是没有问题的,但编造的概念应该满足 MECE 原则,以及剃刀原则。不然,这种编造就太随意了。
2、来自微软
如果不希望自行编造,那么一个正确的来源就是微软本身。
正如微软给自己的孩子起了一个名字,叫:张三。而有人非要告诉你,他叫:李四。当你问及张三和李四有啥区别的时候,往往得到回答:没区别。然后,你就会多记忆一个词汇,渐渐的学习 DAX 变成了一个记忆词汇的游戏。当你发现你的词汇量很大的时候,却无法写出有效的句子。
这里将从零开始使用,一起来看看到底需要几个概念。
当我们不知道一个事物时,我们叫它:东西(Object)。
概念,就是对东西进行描述和限定,让其具有内涵(可以被人用其他概念或常识理解的含义)。当提及某个概念时,可以无任何二义性地锁定特定的东西。
为什么你无法准确地描绘你要的东西呢?因为你脑中的东西没有坚固的无二义性的概念。
很可惜模糊而混乱的概念充斥着在各个领域,这就是常常逻辑性很强的人会发现业务人员描述了两个不同的东西,而业务人员自己却认为他描述的是一个东西。
例如:系统可以导出一张表,业务人员说:这是一张表。而等下业务人员定义了这个表中某个指标的逻辑,是要根据用户的筛选动态计算的,但业务人员仍然要求:系统可以导出这张表。同样是表的概念,但它的内涵已经发生了严重的变化。
所谓数据素养,其重要表现就是业务人员对概念有和分析师一样的严谨觉察和习惯,周围是懂的逻辑且有很高数据素养的同事是一件幸福的事;而身边的老板和同事提出了不同逻辑的东西而又被冠以同样概念将导致很大痛苦。痛苦过的伙伴,请自觉点赞吧。
首先,DAX 起始于数据模型。在数据模型中以表结构存在的东西,暂且先称为基表(base table)。
稍后我们会发现,这里的基表是严谨的概念。
SUM 是一个最基本的函数,本来没有什么好说的。但很快人们会遇到:
这里出现了第一个重要的名词:列引用。
让我们慢慢地写出 SUM 会看到:
会发现:
SUM 需要一个被称为:ColumnName 的东西,该东西称为:ColumnName,其定义来自微软,叫:列引用。
那么 SUM 的准确注解应该是:SUM 的参数,列引用,指向基表中的列,SUM 将对该列的所有数值求和。
随着对 DAX 使用,会继续发现:
此时,会看到:SUMX 的第一个参数叫:表。
接着,会继续发现:
此时,会看到:ALL 的第一个参数叫:TableNameOrColumnName。
如果 ColumnName 叫:列引用,这个概念已经由上面的微软名词坚固地给出,那么,TableName 就应该叫:表引用。这是顺其自然的。
但此时,会立马好奇一件事,同样作为参数,这个叫表的概念和这个叫 TableName 的概念到底是不是一件事?
这里立马构建一个实验来看看:
可以看到,根据微软的说法,ALL 的参数需要使用一个表引用表达式,而不可以是一个表表达式。
由此,我们可以坚定:
而表引用表达式和表表达式是不同的。
此时,我们还携带着的刚刚的问题:这个叫表的概念和这个叫 TableName 的概念到底是不是一件事?
转化为:
表的概念与表引用(TableName = 表引用)的概念是不是一件事?
进一步来实验:
这么用是错误的,如下:
作为对照,这么用就正确了,如下:
其中,
_values 是由 VAR 定义的以表结构存在的东西;而 'Order' 是数据模型里以表结构存在的东西。
按照上文, 'Order' 是表引用表达式,简称表引用,它引用了数据模型中一个叫 'Order' 的基表(基表的事,等下再谈)。
那 _values 又是啥呢?
继续实验:
这样的写法是正确的,也就是说,_values 可以作为 COUNTROWS 的参数,那来看看微软对其参数的定义:
根据微软的定义, COUNTROWS 的参数是一个称为表的概念。
表的概念来了。我们会立马再做一个实验:
可以看出,这个表达形式是正确的。
因此,我们得到一些重要事实:
希望读者你没有被绕晕。
还剩一个问题:到底数据模型中的以表结构存在的东西叫啥?
通过查阅微软的文档可以发现:
https://docs.microsoft.com/en-us/dax/all-function-dax
有这样的描述:
转化为微软自己翻译成的中文文档为:
https://docs.microsoft.com/zh-cn/dax/all-function-dax
其对应描述为:
因此,我们可以坚固地给出:
数据模型中的以表结构存在的东西叫:基表。其中的列,叫:基列。
根据以上极为严谨的逻辑,我们得到了两个重要的概念:
同时,我们还注意到:
由第二条,迅速可得:由 VAR 定义的变量指代的表都不是表引用。
另外,我们还注意到:
这点非常细腻而几乎不被任何人觉察,但它在所有 DAX 函数的语法表现中,以铁律一般存在。
很可惜又很幸运,全网唯一说明此处细节的地方,此时被您看到了。
还有,我们还注意到:
DAX 中的函数,可以使用表引用的一些重要函数却不能使用 VAR 定义的表。如:VALUES 可以使用表引用,但不能使用 VAR 定义的表。
立马得到一个灵魂拷问:那么所有用 VAR 创建的表,需要某种功能时,是否会存在功能缺失的问题?
这才是站在上帝视角,俯瞰 DAX 设计体系,所要提出的灵魂拷问。
我们先给出答案:不存在功能缺失。所以,大家不必担心,当你不能用你认为合理的形式写出一个公式的时候,的确可能存在另一种写法,只是你不知道。由 BI 佐罗打造的《BI 真经》在更新版中将以定式给出全部细节。
爱因斯坦说过,如果不能用一句话给普通人讲清楚一个事,就说明还没有搞懂一件事。
正如爱因斯坦对事物本质的探求,我们假设作为一个财务人,HR,对上述文章全部看不懂,这很正常。
那么,现在我们将用全网最接地气的方法让你瞬间理解以上这么复杂的概念。叙述如下:
DAX 中的表有两类,一类叫基表(base table), 它们是直接位于数据模型中的表;基表(base table)属于表(table);某些 DAX 函数只能用基表作为参数,而不能用 VAR 定义的表作为参数;但可以用 VAR 定义的表作为参数的函数都可以用基表;用基表的方式是它的名字:表引用。
如果你没有听清楚上面的紧密描述,那么下面的版本是送给普通人的:
北京上海的人有两类,一类有户口,一类没有户口。有的事情,要求有户口才行;有的事情,没有户口也行。但不需要户口的事情,有户口也可以。找到有户口的人更容易,即使用:户口本。
有户口的人 = 基表,没有户口的人 = 表。
我们可以这样快速记忆:如果有了户口,各种信息登记齐全,那么查找的时候特别快,一般这样的人工作稳定踏实,相对稳定。而没有户口,随时都可以走,要追溯它的成本也高。与人类社会类似,在 DAX 中,表(人)以基表(有户口)存在后,可以更加稳定存在,而可以用更快的速度得到查询,正是我们需要的。
在我们使用 VAR 的时候,往往在使用一个临时用途的表,常常称为临时表,可以理解为临时工,用完就释放了。而当我们定义某些度量值的时候,会直接使用稳定的基表,也就是稳定的有户口的人们。从这样意义来说:要建立一个好的模型,
当然,与大家的心情一样,用 VAR 定义的用于临时用途的表可能也希望自己有一个户口成为稳定的有户口的进入数据模型的表,那么可以通过计算表(calculated table)将它写入数据模型。
数据模型就像一座城市,要设计好这座城市,就要联合使用稳定和机动,基表和普通表。
总结:
相信,你懂了。没有错,学习 DAX 的过程就是在北上广深努力奋斗而获得户口的过程,当然没有获得户口也不用担心,因为有时候需要的就是机动性强的所有人。
以下内容用来严谨的说明以下基表和表的技术结构,非技术人员可以略过。
基表,以压缩形态,保存在 DAX 存储引擎(VertiPaq 引擎)中,当使用基表时,可以充分发挥存储引擎的快速计算特性,所以基表特别重要。
表,其实是内存中普通形态的表,往往是一个计算过程的中间结构,而这个中间结构往往来自对基表的计算。
使用 DAX 函数操作基表和表,得到最终需要的结果形态。
有时候,可以从基表的计算中直接得到最终结果,这是最佳路径;
有时候,由于计算的复杂,对于基表的计算往往会得到一个中间结构,且会在内存中展开,称为:物化。基于这个结构再计算,得到最终结果。物化时的展开会解压缩,搞不好就把内存给撑爆了。
DAX 引擎在操作几十万数据时,属于舒适区,可以不必在意这些,可以是完全业务导向的,只要可以写出来公式就可以,不用管它的性能。
有了本文作为基础,后续在描述事物的时候就可以精确地使用两个概念:表(table)与基表(base table)。
那么,还有很多关于表的概念是咋回事。
有时候我们会根据目的或作用来定义事物:
目的是临时用一下,所以叫:临时表。
目的是作为分析的维度,所以叫:维度表。
目的是作为分析的事实,所以叫:事实表。
目的是作为连接的桥梁,所以叫:桥表。
而本文描述的表(table)和基表(base table)是根据其底层特质进行定义的。
总结如下:
遗留问题:对于只能使用基表的函数,如何给出替代方案,答案是肯定的,后续分解。
通过本文可以发现一个事:
很多时候,我们被一种按目的和作用给出概念(而非本质特质)去认知事物,这是最普通的。
例如:按照目的可以定义出这么多表,但其本质特征是以压缩形态存储的基表还是普通内存表。这才是本质。
那么,请思考商业智能到底是啥?自助商业智能分析到底是啥?
请不要再用目的去描述这个概念了,例如你可以搜索到:商业智能是用来 xxxxx,解决 yyyy 问题的。这种概念毫无意义。
Power Query 是用来解决 xxxxxxx 的。
Power BI 是用来解决 yyyyyyy 的。
那么,还是没有回答自助商业智能分析到底是啥?我们要知道的是本质,不是目的。
类似的,HR 是啥?运营是啥?财务是啥?不要用目的去描述,用某种本质去描述,这是一种思维模式,帮你发现事物本质密码的思维模式。
还记得学生时代,总是纠缠老师,问:到底啥是啥,请不要告诉我啥是干嘛的,我要知道的是啥到底是啥。幸运的是,我的老师,巧巧地告诉了我这个事,不要用目的去定义事物,而是要发现事物的本质规律去理解事物。希望这条原则可以帮助大家修复受损的好奇心,同时不要陷入目的式概念的绕来绕去陷阱。
因为,目的只能定义欲望;而现实需要按自然规律去创造。
请反思是不是很多概念定义了一堆目的和作用,一到落地就是像字母一样,一个个来,毫无洞察性。难倒不能提炼个密码吗?学习 BI 佐罗出品的《BI 真经》,让数据真正成为你的力量,知道为啥用:真正二字了吧。涨价中... 看懂这事的人早收集齐了,希望你看到的不会太晚。