大家好,前几天我偶然发现国产 BI 之“翘楚”帆软和“新秀”观远,几乎同时发布了窗口函数(window calculation)功能,非常好奇。
众所周知,窗口函数是完全以分析为目的的高级函数(function),在部分工具中可以称之为“表达式”(expression)。它的主要目的是:跨行不聚合,比如排序、索引、累计汇总、移动汇总等。
过了中秋佳节,今晨简单评测如下。借此功能,可以一览国产 BI 两个典型产品的发展方向,甚至可以一览二者背后的开发力量。
特别说明:本文未经任何厂家审议,未接受任何厂家直接或间接“资助”。全文仅代表个人观点。时间所限,部分地方未能详尽展开,有意者可参考《数据可视化分析(第 2 版):分析原理与 Tableau、SQL 实践》第九章相关介绍对比,即可获得更深刻之见解。
1、帆软 BI 的窗口函数简介
2、观远 BI 的表计算简介
3、表计算的难点和二者对比
1、帆软 BI
FINEBI6.1.2版本发布“窗口函数”,官方帮助介绍如下:
WINDOW 窗口函数常用于行间计算的场景,在对数据进行分组、排序后,对窗口上下限内的数据进行计算。 能够单独输出字段,或和 DEF 函数组合使用。对分析视图的字段进行计算时,窗口函数比使用 EARLIER 函数进行跨行计算更简单、更易理解、性能更优。 https://help.fanruan.com/finebi/doc-view-2470.html
在后面的一段中,官方又介绍了它的使用场景:
WINDOW 函数基于分析视图进行聚合计算,即依据已生成的组件结果进行计算(不包含明细表)如
https://help.fanruan.com/finebi/doc-view-2470.html
接下来,到了一个充满歧义、甚至错误的描述,这段话甚至出现在了产品中,暴露了官方的理解水平。稍后评说。
“窗口函数基于「分析视图」进行计算,函数内的指标/分组字段/排序字段需要均为聚合性质,且维度字段均需要来源于分析视图 ” https://help.fanruan.com/finebi/doc-view-2470.html
同时,帆软 BI 的函数语法,走向了 PowerBI 而非 Tableau 的路线,将所有的控制语法都放在表达式中完成。官方介绍如下(此处格式略有调整):
WINDOW 函数表达式: WINDOW_汇总方式( 指标 , [分组字段1, 分组字段2.... ], [排序字段1,排序方式, 排序字段2, 排序方式...], [窗口上限,窗口下限]) https://help.fanruan.com/finebi/doc-view-2470.html
帆软的窗口函数必须明确指定分区(partition by)和寻址(order by)依据;换句说话,必须明确的分配视图中所有字段的角色——非此即彼,绝无例外。
当然,PowerBI 和背后的 DAX 其实也在代码中支持相对方式(rel 和 abs 两个参数)。从这个角度看,帆软 BI 只学习了一半(也许只想学习一半)。稍后评说。
2、观远
再看观远6.6的“表计算”。
从名字到函数定义,观远 BI 几乎是贴着 Tableau 而去的,说致敬也好,说模仿也罢,这条路走的比帆软 BI 更远一些。
相比帆软 BI 的官方介绍,观远在定义上似乎在避免用专业术语(当然这也成功免于陷入理解的陷阱而被我苛责)。
表计算无需用户编写复杂公式或使用自定义计算字段,通过直观的可视化配置方式,快速实现多种常见的高级计算及各计算间的嵌套计算。 在数值栏中,点击需要添加表计算的字段,在下拉菜单栏中选择“高级计算-表计算”,即可弹出表计算设置框。 https://docs.guandata.com/article/1/656332031604555776.html
观远的界面,很明显地彰显了它的“tableau 气息”,从表计算设定到“二次计算”的高级扩展,都学习地有模有样,甚至还针对不同的表计算做了定制化的交互界面,这确实让我颇为意外(排序的弹窗和差异的弹窗不同)。
从功能上看,观远支持“7种方式”,并将其写在表计算的两步骤中:设置计算类型、设置计算依据。
表计算主要分为两个步骤,确定计算类型 和 确定计算依据。
https://docs.guandata.com/article/1/656332031604555776.html
从观远的界面和帮助来说,观远很明显走向了 “Tableau 方向”,这和帆软的“PowerBI”方向截然不同。观远虽然使用了第一个、上一个这样的控制符,但是似乎都没有给用户 First() 、-1 这样的代码控制方式。这很好地体现了它的“易用性”特征,当然也伴随着“深度不足”的隐忧。
写到这里,我实在忍不住要说,先从官方帮助的介绍和详尽程度来说,观远明显要比帆软高出两个段位。
帆软的帮助:第一简陋,第二瑕疵。忍不住吐槽,可以对比如下两个文件,稍后再说。
https://help.fanruan.com/finebi/doc-view-2470.html
https://docs.guandata.com/article/1/656332031604555776.html#nav-2-H2
3、表计算的难点和二者的问题
窗口函数是每个分析工具中至关重要的功能,从 Excel 透视表,到 SQL/DAX,以至于 PowerBI、Tableau,莫不如此。
在《数据可视化分析(第 2 版):分析原理与 Tableau、SQL 实践》第九章中,喜乐君介绍了窗口函数在整个计算体系中的位置。它代表“抽象的二次抽象”,但又不是“聚合的二次聚合”,是偏移计算的最重要实现方式。
如下所示(当然,这个图如今也有些瑕疵):
先说窗口函数的定义。
挑剔地说,窗口计算不是“行间计算”(帆软官方用语,当然也是喜乐君早年用语),因为“行间计算”是窗口计算的必要但不充分条件——SUM 聚合也是行间计算。
准确地说,窗口计算是“偏移计算”,而合计所代表的“行间聚合”只是窗口函数的特例,可以同时用子查询、LOD 表达式完成(在《数据可视化分析》第九章就是用合计开篇)。
从定义的角度看,帆软的官方用语明显有失严谨,观远则完全不做定义上的描述(直接用功能枚举)躲过一次可能的批评。
接下来,窗口计算的难点是如何控制分区和方向。
窗口计算的体系大多沿用 SQL 的逻辑,毕竟二十多年前 SQL:2003就以国际标准的方式予以确定。其中的关键是:
通常,前者表示绝对的指定(absolute),后者表示相对指定(relative)。这也是 Tableau 过去将近20年一贯的体系(Tableau 在2006年推出快速表计算,而后在2010年推出完整表计算功能)。
在学习 Tableau 过程中,用户可以直接把“表计算”的功能与 SQL 对应,相对和绝对的两种计算依据设定方式也可以自由切换。这个易用性的体验,我想没有第二个产品可以比拟。
相比之下,DAX 的 window 窗口函数是2022年年底发布的。它也支持在代码中指定partition 区间,并支持 rel 相对和 abs 绝对两种方式。可惜帆软在学习的路上只选了最容易的绝对指定方式,帆软的快速表计算无法被二次编辑,这违背 BI 应用的易用性需求。
了解了表计算的功能和设定方式,我们回来说帆软和观远的差别。
1)帆软更像 PowerBI 路线,观远完全是 Tableau 路线。
“PowerBI 路线”意味着它对使用人员的要求更高,稍有不慎就会卡住;而“Tableau 路线”则对用户更加友好,就像从早年的 DOS 界面到 Window 的 UI 界面一样。
当然,观远在模仿过程中,也许是为了“易用性”因此遮挡了自定义的路线,所以官方文章中没有出现 First、Last 等代码中必然有所对应的函数,这就影响了它的“深度”。 这和喜乐君一向的评价相呼应:“易用有余,深度不足”。
所以,二者其实都不足以挑战 Tableau 的地位。观远可以很好地成为学习 Tableau 的跳板,降低了学习者的“学习成本”,更容易形成两个产品高低搭配的格局。帆软 BI 则似乎是奔着 PowerBI 的 Report 和定制化 BI 而去的,难道是发现 Tableau 太难学了?
2)帆软和观远对应的阶段:早晚之别
帆软在之前已经有简单的表计算功能,能够完成占比、累计、排名、同环比等功能。这有点像 Tableau 的发展路线,先在2006年推出“快速表计算”(Quick Table calculation),四年之后才推出完整的“表计算函数”,用户可以用 Window_sum、running_sum、rank、index 等函数完成自定义配置甚至组合。
帆软快速计算概述
https://help.fanruan.com/finebi/doc-view-1686.html
相比之下,观远明显就是晚辈了,它成立时间太晚(2016),好在它使用了最新的 Spark 引擎,绕过了帆软的一些老路,之前可以用 Spark SQL 完成明细级别的窗口函数——当然这不是业务分析之路。
观远 Spark窗口函数:
https://docs.guandata.com/article/1/428146556726673408.html
如今,帆软尝试补上自定义函数的不足,不过似乎走向了 PowerBI 方向,而非 Tableau 方向;而观远则尝试先完成 Tableau2006年的阶段——用高度定制的“快速表计算”帮助用户完成聚合后的二次分析。
虽然观远发展更晚,但明显在“快速表计算”上的表现完胜帆软 BI 简陋不堪的“快速计算”,目前我也看不出来帆软有改进“快速计算”的苗头。可以预料的是,观远会在未来几年中推出类似于 Tableau 的表计算体系:
3)高级功能上,帆软没有“二次计算”,和 DEF 的嵌套结合语焉不详。
表计算本身就是“二次抽象的代表”,但在一些专业场景下,比如金融行业计算 YTD_ANR,会出现表计算的二次表计算的情景,这就是 Tableau 中“二次计算”的高明之处,它用界面点击代替了复杂代码。
这一点,观远至少是有所挑战的,虽然它也没有达到 Tableau 的高度。如下所示,展示了观远表计算“二次计算”的官方用途(红色文本是喜乐君所标记)。
我个人很期待的是,帆软 BI 写到的嵌套场景:不是表计算的二次嵌套,而是和 DEF 表达式的嵌套。如下所示,
嵌套场景:当 WINDOW 和 DEF 类函数嵌套使用时,基于 DEF 函数下的独立视图进行计算,这种情况下如果使用的是 DEF 函数(指定维度)可输出明细级别的字段。 DEF+WINDOW 的嵌套场景下支持在自助数据集和明细表中使用 WINDOW 函数。 https://help.fanruan.com/finebi/doc-view-2470.html
我对此寄予深切的期待,可惜官方几句说过,我没有找到对应的介绍,又难以脑补上面一段话的背后“深意”。这个功能的复杂性,其实不亚于“二次计算”,但是稍不留神,定然也会成为下一个“现眼包”。
4)帆软在功能上存在明显表述错误。
之前我曾建议,BI 厂家应该由产品经理写帮助文档,这其实是检验理解的很好的方式。在帆软这次的更新中,我故意写错了一个表计算(删除了分区部分)。英文版本中跳出来的错误提示依然是中文的,中英文都会出现一段在我看来完全错误的话(我的浏览器近期工作需要改为了英文,算是“意外之喜”,绝非故意来找茬)。
我忍不住吐槽的是,不仅程序上的帮助明显存在歧义,而且“官方帮助”也简陋不堪,错误连篇。这句错误的话强调如下:
分析视图:在可视化组件的编辑页面,对数据进行汇总、聚合和可视化 窗口函数基于「分析视图」进行计算,函数内的指标/
分组字段/排序字段需要均为聚合性质,且维度字段均需要来源于分析视图 https://help.fanruan.com/finebi/doc-view-2470.html
表计算的是对一个聚合计算的偏移计算,偏移的控制是视图中的维度决定的,比如 partition by 地区,order by 日期。绝对不能说“分组字段/排序字段需要均为聚合性质”。
当然,我猜测,帆软想表达的是:窗口计算中的聚合、分组、排序字段,都必须来自于聚合表,不能出现视图中没有的其他字段。
如果是这样,为什么不使用弹窗编辑呢,这样在程序上可以更好地控制字段边界。
说到这里,英文更是让我看了大为惊讶,当然,大概率是帆软内部有机器翻译或者临时工,应该不是产品经理所为。否则,怎么能用 group 称呼表计算的“分区”,而用 rank 对应表计算的“排序”呢?简直是自造体系,胡言乱语了。
更可笑的是,指标竟然是 indicator,而不是使用 Metrics 或者 measure 这样更加严谨的词语。
Indicatior之所以能被理解为“指标”,是因为它所处的上下文是 KPI(key performance indicator)——是“绩效”performance 让它成为“指标”,而不是 indicator 自身可以称之为“指标”。
一个产品背后的知识和技术底蕴,要经得起推敲。
老一代产品再不努力,真要被后来之辈赶上啦。