"横向取总和,纵向取平均,角落取总值"的烧脑题

Tableau交叉表经典面试题:横向取总和、纵向取平均、角落取总值的表计算实现。

在知乎上看到Michael Ye写的一篇「一道烧脑的Tableau面试题」,特别吸引了我。

知乎文章: https://zhuanlan.zhihu.com/p/96494410

这道题很有挑战,一开始我看到也是一头雾水,完全不知道怎么做,但是看完大神讲解,大致就理解了思路,作者已经提供了三种计算方法。后来发现这个题目和WOW2020 Week29的挑战有相通之处,也可以用挑战中用到的SIZE函数来解决。

WOW挑战: https://www.workout-wednesday.com/2020w29/

所以我按照大神的解题思路,用SIZE函数尝试解题,也得到了相同的结果。强烈建议大家去看知乎这篇文章,理解作者的解题思路,才能在以后遇到问题时不慌张。

这道题的关键点就是如何确定分区,原文中第三种方法就是用COUNTD([Ship Mode])和COUNTD([Region])的值来确定分区,而SIZE函数本身就是确定分区中的行数,和COUNTD其实是同样的效果。

所以我创建了两个计算字段:SIZE([Ship Mode]) 和 SIZE([Region])

看一下计算的结果:

这样就可以根据两个计算字段SIZE的值来判断不同的区域,从而来进行分类计算了。

但是这之前还需要新建一个计算字段

因为视图的详细级别,是根据每笔明细来计算合计的,SUM函数结果是没有问题的,但是AVG的计算结果就是每笔订单的平均数,而不是1区里4个值的平均数,所以这里需要FIXED指定详细级别。
IF //计算4区
  [size by ship mode]=1 and [size by region]=1 
  then SUM([LOD sum sales]) 
//计算2区
ELSEIF [size by ship mode]=1 and [size by region]=2 
  then AVG({FIXED [Region],[Ship Mode]:SUM([Sales])})
//计算3区
ELSEIF [size by ship mode]=2 and [size by region]=1
  then AVG({FIXED [Region],[Ship Mode]:SUM([Sales])})
//计算1区  
ELSE AVG({FIXED [Region],[Ship Mode]:SUM([Sales])})
END
和上面的计算原理是一样的。

结果与原文一致,思路与原文第三种方法类似,略有不同。

写这篇文章主要是想说,条条大路通罗马,同样的问题在Tableau中可以用不同的方式来解决,但是都需要了解底层逻辑。顺便推荐一下WOW挑战,十分烧脑,只要能坚持几期,肯定会有收获。同样的挑战,每个人的解题思路都会有不同,非常锻炼技术。如果不会,还可以直接下载参与者的Viz结果来学习。

WOW官网: https://www.workout-wednesday.com/

📖 相关文章

📌 本文核心要点
  1. Tableau 交叉表的分区逻辑 = 行维度 × 列维度
  2. 用 SIZE 函数判断每个单元格所在的分区类型(1区~4区)
  3. FIXED LOD 用于在计算中消除视图详细级别的影响
  4. 同样的结果可用多种方法实现——关键是理解底层分区逻辑

No comments yet