按:上周高铁上即兴写了一篇帆软的文章(帆软BI6.1升级有感:“天下苦秦久矣”),在同行中引起一阵热讽,在帆软中引起少许“喧噪”。我本以为帆软市场部会投诉我的文章,它没有;我本以为某些人会来约个咖啡聊聊(取经也好,灭火也罢,我内心还是期望国产 BI 向好的),他们没有。
我的一些帆软读者忍不住来问我莫非“同行相争”,还传达了一些内部的反馈意见,大致就是“诽谤!要对帆软有信心!净扯概念、敢说具体场景吗!!”。
既如此,我搁置了原计划 FineBI6.1的视频深度测评,老大不犯错,别人哪有机会呢?但这几天又看到一篇“李启方之流”发表的标题党文章,看了官方的 DEF 案例。我想公众号中补充一下 DEF 吧。
6月20日知乎推送了一篇“李启方”的“新文章”(其实是去年老文章翻新),标题是:
在数据可视化工具的选择中,PowerBI是最优方案吗,需要考虑其他可视化工具吗?
通篇没有一个 PowerBI 的图,却敢于含沙射影怼隔壁“帕弟”,文章罗列四点理由,其中第二条是:
这文风,很帆软啊!
我只觉得无知者无畏,竟然想以 DEF 单挑 DAX 和 LOD!哪来的勇气说“不输 PowerBI 和 Tableau 的 DAX 和 LOD 函数”的!
细看案例,惊呆了我!这 TM 是啥!
只要对 Tableau和 PowerBI 稍加了解,你就会知道文章的案例不仅条理不清、混淆是非,而且对宣传帆软DEF无益、甚至有害。我很好奇,写这些文章的“帆软御笔”根本没有 弄清楚 DAX 和 LOD 的区别。
我们看看“李启方之流”的一个案例:
举个例子吧,DEF函数的语法是: def(指标, [维度1,维度2,...], [过滤条件1, 过滤条件2,...]) 是以函数中维度为分组、函数中过滤条件做过滤,实现对指标的计算。
“比如对这张表,我想计算A城市的销售额,可动态汇总车型、月份等。”
(图片来自“李启方”)
接下来,帆软的 DEF粉墨登场了,“李启方”用了下面的Def函数:
DEF_ADD(SUM_AGG(${销量}*${单价}),[${城市}],[${城市}="A"]
以此表示,“通过自定义静态维度+动态维度,能实现任何逻辑的聚合 ”。
如下图所示,问题详细级别(粒度)是城市、车型、月份;指标(度量)是销售额、“城市A 销售额-静态”和“城市 A 销售额-动态”。
我们先不说什么是“静态维度”“动态维度”(用新概念模糊简单问题,这个我都不想吐槽了)。
如果不是因为图中画出来了红框,恐怕你不知道上面的 DEF 函数对应的是第三列“城市 A 销售额-动态”吧。
1、DEF_ADD
先看这里最重要的、无知的“城市A 销售额-动态”。
从图中可以看出,“城市A 销售额-动态”无非、仅仅、只不过是和问题详细级别(粒度)完全相同的聚合指标值,增加了“城市= A”的过滤条件而已!
如果为了得到上面的结果,最简单、最高性能的方式绝对不是 DEF/LOD!!!
哪怕你只有 Excel 的基础,你都应该知道,这只是一个最简单不过的 SUM+IF 组合,Excel 还可以用 SUMIFS 完成。只需要嵌套筛选条件(过滤)的聚合好了。比如(帆软IF 语法可能略有差异):
SUM_AGG(IF [${城市}="A" THEN ${销量}*${单价}) END)
这么一看,上面兴师动众的整个 DEF_ADD,简直就是“脱裤子放屁,多此一举”。无谓的“脱裤子”多了,系统净做无用功,人家跑出去几百米了,这还在下蹲呢,性能不就下来了嘛!
我不惮以恶意揣测,也许这个例子只是为了说明 DEF_ADD 的用法?那很抱歉,你这个例子“有毒”,不仅没有告诉用户这个函数的必要性,而且培养了更快摧毁帆软 BI 的“好习惯”。
你再想想,为什么叫“城市A 销售额-动态”?
2、DEF
啥叫动态,啥叫静态?? 反正我是不明白!我们看看“城市A 销售额-静态” 这个指标。
从图中可以看到它其实是以 “城市 A”为筛选条件的 “车型销售额”(比如11200K 是思域两个月的销售额合计,而9600K 是轩逸两个月的销售额合计)。
更准确的说,“城市A 销售额-静态”结果值的“分类依据”是【车型】(相当于 SQL 的 groupby),而“筛选条件”是“城市=A” (相当于 sql 的 where)。
从这个角度看,名字称之为“城市A 销售额-静态” 简直就是愚昧和无知!完全没有体现这个指标的核心:指定车型为聚合分组依据。
为了对得起“静态”二字,大概率该字段对应的 DEF 是:
DEF(SUM_AGG(${销量}*${单价}),[${车型}],[${城市}="A"]
不知道为什么不写?脑子转不过来了?
当然,如果单纯为了得到上面的结果,最简单、最高性能的方式绝对不是 DEF/LOD!!
只有自以为聪明的人才会拿着“一把锤子”把所有东西都当做是“钉子”!只是帆软还没有表计算,这里恨不得把更适合窗口函数完成的事情都称之为 DEF 的功劳(虽然二者都可以完成,但窗口是此处最优解)。
也许,这就是文章不写这个 DEF 函数的原因?
3、不输Tableau的勇气呢?
说到这里,我都不好意思评价“李启方”用Tableau 的水平了,为了一个本就“错误的题目”,加上了“极不准确”的字段名,然后还强行用 Tableau 的拙劣语法做个死亡陪衬。
他说,用Tableau通过if判断和INCLUDE表达式:
if [城市]='A' then {INCLUDE [城市]:sum([单价]*[销量])} end
最后得出来一个“自慰”的结论:
可以看出对于复杂函数计算,FineBI和Tableau都有相应的函数,复杂度差不了多少,但FineBI把判断语句集成到DEF后会更为简洁易懂。
我们自己基本都不这么写 LOD 表达式,更何况这里有“小学生级别”的简单写法:
SUM (IF [城市]="A" THEN [销量] * [单价] END)
Excel 就能干的活儿,关人家LOD 什么事儿呢??
4、还想挑战DAX?
文章还说,“新推出的def函数不错,弥补对标了PowerBI和Tableau的DAX和LOD函数”。
就不知道为什么没有写Calculate表达式的勇气?
还是没有底气?
Sales_of_city_A =
CALCULATE (
SUM ( Sales[Sales Amount] ),
Filter( Sales, 'Sales'[City] = "A" )
)
你能用“外部筛选器”“内部筛选器”讲清楚人家的逻辑吗?
这里有DEF 中用到的预先分类聚合吗?
这里Filter 是一个中间表,你是吗?
其实人家和你DEF 根本不是一个事儿!!你这就好像和武松比打牌,和鲁智深比娇羞。
无知者无畏。
5、后记
对了,“李启方”在文章中,刚开始自嘲了一下,“在之前用5.0的时候,明显发现函数功能比较拉胯,跟Powerbi的Dax没法比。”
不用自嘲,5.0不行,6.0也一样。如果说6.0的 DEF 还有一些实质性的进步的话,也已经被你们这些不着头脑的官方案例给糟蹋没了。
还“不输 DAX 和 LOD”?
我之前见过帆软的宣传文章过头,但没有见过技术文章这么“无知无畏”的。
对了,帆软的很多人学习 Tableau 的 LOD 表达式,还把我的很多文章搬到内网(未经授权),欢迎你们“致敬” Tableau LOD案例,但请收起来你们的傲慢。
注:
1、帆软的“过滤”,基本对应 Tableau 的“筛选”,但和 PowerBI 中的“筛选”截然不同;
2、帆软没有明确的“详细级别”(LOD)的概念,文章使用了“详细级别(粒度)”辅助理解;
3、“李启方”虽然是个人名义,但其实是帆软官方“小号”,其公众号“数据分析不是个事儿”对应的经营主体(宁波马铃薯信息科技合伙企业)为帆软持股平台。因此内容可以视为帆软 BI 市场部和其他部门的“杰作”。
4、子曰:不患无位,患所以立;不患莫己知,求为可知也。 学习伟人挺好,也别忘了孔老夫子。