什么是逻辑计算?
如果我用通俗一点的语言来解释逻辑计算的话, 逻辑计算就是"判断". 判断一个数值是否大于100? 判断一个日期是否等于今天等等. 判断的结果只有两种可能, 要么就是"是", 要么就是"否". '是‘ 就是True, '否‘ 就是False.
简单的逻辑运算只需要判断一次, 得到一个是或者是否, 而复杂的逻辑运算就需要判断多次, 然后把每一次判断的结果连在一起看. 最终得出一个最终的'是' 或者是'否'.
那么这样一整个过程就叫做逻辑运算.
既然它是运算, 那么它就像其他的运算一样就自己的运算法则, 有自己的运算符, 有自己的规则. 也就当然有它自己的技巧. 这些我们在后边会详细讲解.
为什么我们需要逻辑计算?
逻辑计算在Tableau的日常运算当中占有很大的比重, 这是因为我们有大量的Filter都是通过逻辑运算来实现的. 比如我们只想要保留今年的数据, 我们就需要'判断' 日期的年是否和当前这一年是否一样. 有的时候我们只想显示当前未发货的订单, 那么可能我就需要创建一个逻辑计算, 让订单的状态等于未发货.
如果你有认真学习前边Filter那一课的话, 那么我在10.2一课介绍了一种叫做'间接过滤'的Filter, 而逻辑计算就是我们用在IF后边的那个重要组成部分.
逻辑运算有哪些组成部分?
理解逻辑运算, 需要按照由内到外的顺序, 因此我们的学习也按照这个顺序. 首先是最内层的运算符, 我们也可以理解为简单判断. 他们运算返回的结果只有两个值True or False.
第一层也是最内层:
是否等于 =
是否大于 >
是否小于 <
是否为空值? ISNULL()
是否为日期? ISDATE()
是否在列表里? IN
在这其中, 我们最常见的就是前三个, [sales]> 1000 我们的销售额是否大于1000? [sales] = 1000? 销售额是否等于1000
在使用前三个的时候, 我唯一需要强调的就是你运算符的两侧必须是同一种数据类型. 数字是不能和文字比较的, 文字是不能和日期比较的.
ISNULL( ): 判断一个计算是否为空值的一个函数.
ISNULL([Sales]): 判断我们的销售额是否为空值, 如果Sales这一列当中有哪一行没有数据, 它就是会返回True, 如果有就返回False
ISDATE( ): 判断一段文字, 注意啊⚠️是文字, 是否为日期格式的函数.
ISDATE("2025-01-01") 这就会返回True, 如果是ISDATE([Customer Name]) 这就会返回False
IN: 是否在我的名单里?
IN 这个运算单独通过描述不好理解, 我来举一个例子. 在Sample Superstore里边, 我们有一个Column叫做Regional Manager. Region Manager下边一共有四个人, 分别掌管四个区.
这四个人分别是 Chuck Magee, Fred Suzuki, Roxanne Rodriguez 和 Sadie Pawthorne. 现在,我只想保留我感兴趣的两个Regional Manager的名字, 分别是Chuck Magee和Fred Suzuki.
我创建了一个使用IN的计算: [Regional Manager] IN ( 'Chuck Magee', 'Fred Suzuki')
在这其中你可以看到Chuck和Fred那两行返回的是True, 另两个Regional Manager的名字后边返回的是False.
到这IN就讲完了吗? 如果要是这就讲完了 不就跟外边那些水课一样了吗. 那么下来出道思考题
既然我想要保留这两个Regional Manager, 我为什么不直接把[Regional Manager]拖拽到Filters那个区域, 使用Direct Filter, 然后在弹出的选项里边勾选这两个名字不就完了吗? 为什么还要创建一个这样的计算呢?
左边的这个截图完全可以实现保留这两个名字的目的
答案:
当我们使用这种方式来过滤数据的时候, 就意味着你已经选择了使用Direct Filter, 也就意味着在同一个工作表内的所有计算都会受到你这个Filter的影响. 而假设你想要画两条线, 一条线代表所有Regional Manager的销售额, 而一条线是只有这两个人的销售额的时候, Direct Filter就将无法满足你的要求.
数据源的变化. 我们的数据源是有可能会变的. 此时此刻的数据里是这四个Regional Manager, 但是下次数据更新的时候可能Fred就不在了. 如果人员名单频繁变更, 而你的关注点又只在这两个人身上的时候, 使用IN这个计算可以确保每一次数据里只包含这两个人, 如果有就显示, 如果没有就不显示.
写到这里, IN还没有结束
我们现在再回过头来看看 [Regional Manager] IN ( 'Chuck Magee', 'Fred Suzuki') 这个写法
现在我们把注意力放在整个表达式的后半部分('Chuck Magee', ‘Fred Suzuki')
我要强调两点: 第一 这个格式, 一个括号, 里边包含各个值, 然后用逗号分隔的形式叫做列表. 它是用圆括号的而不是像Python一样, 是用[ ]方括号的.
第二, 这个列表不能被计算所替代! 一定是一个固定的列表
Tableau不支持这种 [Regional Manager] IN [Regional Manager List]的格式, 换句话说, 一个calulated field in calculated field的格式.
你是没有办法把 ( 'Chuck Magee', 'Fred Suzuki') 保存成一个计算的. 在一些比较复杂的使用情景当中, 你可能想说, 品类A, 我想保留Chuck, 品类B 保留Chuck+ Fred, 品类C保留Sadie+Chuckd等等, 这种情况下你是不能使用IN这种写法的, 因为你不能创建一个动态的列表, 这个列表里的内容必须是完全固定的. 但这并不就是说做不到, 这是因为本质上
IN这种写法就是一系列OR的简化.
([Regional Manager] = 'Chuck Magee') OR ([Regional Manager] = 'Fred Suzuki')
上边这种写法和IN完全等同. 为了实现你要的动态效果, 你需要把IN 转化为OR才行. 我会在下一课来解释这个部分.
第二层 AND, OR, NOT 和( )
在第一层的判断计算结束之后, 我们就需要第二层的这些运算符来把第一层的计算关联起来形成一种更复杂的判断.
比如 [sales] <1000 and [sales] > 500 : sales大于500 但是小于 1000
[sales] <1000 OR [sales] > 500: sales或者大于500, 或者小于1000 都行.
NOT [Sales]<1000: Sales不能小于1000, 也就是Sales必须大于等于1000
当我们在外边加上括号, 那么括号内的计算优先级更高: ([sales] <1000 and [sales] > 500) OR [sales] > 10000 先算括号里边的, 后算括号外边的
第二层的难点: 你写的逻辑要符合逻辑
Tableau只会给错误的语法和表达式报错, 但是没有办法给错误的逻辑报错. 因此在创建逻辑计算的时候, 你必须非常认真的检查你最后组合在一起的逻辑运算是不是make sense.
让我们来看下边这两个例子
[Sales] < 1000 OR [Sales] > 500: 这个条件就是一个无用的条件, 如果我们认真审视这个条件, 任何一个数值都满足这个条件, 这个条件所返回的值永远都是True, 而不会有False.
[Sales] < 500 AND [Sales]>1000: 这个例子是上边这个例子的又一个极端, 销售额不可能永远同时既小于500又大于1000, 这个条件所返回的值永远都是False.
很多这样的计算都是在无意中写出来的. 如果你有意识的去检查或者说测试就说明你潜意识里知道这些地方容易犯错. 而新手一般就是在这些地方犯错而不自知.
经验之谈, 悔恨之泪: 很多你卡了很长时间解决不了的问题都在于你犯了逻辑错误而不自知,你所期待的逻辑顺序和实际的逻辑运行顺序是完全不同的.实际运行下来要么都是False, 要么都是True.
高级篇: 如何检查我的逻辑运算创建的是否正确?
快速检查法: 当我们创建了这个逻辑计算之后, 比如[Regional Manager in My List] 这个计算, 最基本的就是把它拖拽到Tableau当中时, 你应该能够同时看到True和False并存. 如果你看到只有True, 或者只有False, 那么大概率,你创建错了.
以左边这个图为例, 我们的计算在创建完之后, 同时会出现True和False, 说明至少这个计算成功了一半. 不是全True或者全False
Direct Filter检查法:
光用快速检查法还不够, 我们还需要更细致的检查. 比如像IN这种计算, Direct Filter检查法最合适. 我们把Regonal Manager in My List拖拽到左上角的Filters选择True. 然后把Regional Manager放在Rows上, 这时候我们可以清晰的看到, 当前所显示的Regional Manager正是我们想要保留的Regional Manager的名字.
IN 后边的list对格式有非常高的要求, 大小写, 空格必须要一模一样
Parameter检查法:
这是最复杂, 但是也是最全面的检查法, 它主要针对数据不全的情况. 有的时候你的数据并不能总是cover所有你想象中的情况. 你设置的一些极端条件可能在数据当中并不能体现出来. 这个时候你就需要首先用Parameter来代替数据中的field进行测试, 然后再替换回去. 在使用Parameter的时候, 你通过手动设置Parameter的值来不断调整,看看在一些极端情况下, 逻辑运算的结果是否正常. 这个部分显然超出了初级课程的内容, 我只是在这里稍微带过