将Tableau计算语句转换为SQL Server查询时的CASE语句问题咨询
嗨,Jen!我来帮你解决这个Tableau转SQL的问题,看起来你在CASE语句的语法和逻辑对应上遇到了小麻烦,咱们一步步理清楚。
首先,先看你的Tableau原语句:
IF ([CodingChange] ='Yes' OR [QueryOpportunity]='Yes') THEN [ActualLift] END * IF ZN([!BaseRate]) > 0 THEN [!BaseRate] END
这个语句的本质是两个独立的条件判断结果相乘:第一个IF判断是否返回ActualLift,第二个IF判断是否返回!BaseRate(其中ZN()是把NULL转为0后再判断是否大于0),最后把两个结果相乘。
而你写的SQL错误在于,把两个独立的条件判断塞进了一个CASE语句里,这不符合SQL CASE的语法规则——SQL里的CASE是一个单一的表达式,不能在CASE内部直接用*连接另一个WHEN分支。
正确的SQL写法
你需要把两个条件判断拆成两个独立的表达式(可以用CASE或者更贴近Tableau的IIF函数),然后再相乘:
方式1:用CASE语句实现
[Obtained Lift -] AS ( CASE WHEN ([CodingChange] = 'Yes' OR [QueryOpportunity] = 'Yes') THEN [ActualLift] -- 这里不写ELSE的话,不满足条件时返回NULL,和Tableau原逻辑一致 END ) * ( CASE -- 用ISNULL()模拟Tableau的ZN(),把NULL转为0后判断 WHEN ISNULL([!BaseRate], 0) > 0 THEN [!BaseRate] -- 同样,不写ELSE则返回NULL END )
方式2:用IIF函数(SQL Server 2012及以上支持)
IIF函数和Tableau的IF语法几乎一致,写起来更简洁:
[Obtained Lift -] AS IIF([CodingChange] = 'Yes' OR [QueryOpportunity] = 'Yes', [ActualLift], NULL) * IIF(ISNULL([!BaseRate], 0) > 0, [!BaseRate], NULL)
如果希望不满足条件时返回0而不是NULL(比如避免最终结果出现NULL),可以给CASE/IIF加上ELSE 0:
[Obtained Lift -] AS ( CASE WHEN ([CodingChange] = 'Yes' OR [QueryOpportunity] = 'Yes') THEN [ActualLift] ELSE 0 END ) * ( CASE WHEN ISNULL([!BaseRate], 0) > 0 THEN [!BaseRate] ELSE 0 END )
关于CASE语句多WHEN和Tableau ELIF的对应
你的第二个问题非常好:SQL CASE里的多个WHEN子句,完全对应Tableau里的ELIF(或者IF ELSE IF)逻辑。比如Tableau里的:
IF 条件1 THEN 值1 ELIF 条件2 THEN 值2 ELSE 值3 END
转换成SQL就是:
CASE WHEN 条件1 THEN 值1 WHEN 条件2 THEN 值2 ELSE 值3 END
SQL会按照WHEN的顺序依次判断条件,找到第一个满足的条件就返回对应的值,后续的WHEN会被忽略,和Tableau的ELIF逻辑完全一致。
希望这些解释和代码能帮到你,如果还有其他问题随时问!
备注:内容来源于stack exchange,提问作者Jen

