检查多列中的null和0

时间:2016-08-12 08:57:23

标签: sql oracle

我在Oracle DW中有一个表,其中包含以下列:

Turnover_In
Turnover_Out
Revenue_In
Revenue_Out

对于Turnover_InTurnover_Out,我需要检查该行上Turnover_InTurnover_Out的值是null还是0,如果是在这种情况下,我需要将Revenue_InRevenue_Out的值输出到相应的列(Turnover_InTurnover_Out)。

源数据的外观示例:

Revenue In      Revenue out     Turnover in     Turnover out
                0               1000            1500

应该变成以下内容:

Revenue In      Revenue out     Turnover in     Turnover out
1000            1500            1000            1500

我现在尝试了以下内容:

case
    when rev.revenue_in in (null,'0')
    or rev.revenue_out in (null,'0')
    then tur.turnover_in
end "Revenue in",
case
    when rev.revenue_in in (null,'0')
    or rev.revenue_out in (null,'0')
    then tur.turnover_out
end "Revenue out"

case
    when nvl(rev.revenue_in, '0') = '0'
    or nvl(rev.revenue_out, '0') = '0'
    then tur.turnover_in
end "Revenue in",
case
    when nvl(rev.revenue_in, '0') = '0'
    or nvl(rev.revenue_out, '0') = '0'
    then tur.turnover_out
end "Revenue out"

......但似乎没有任何效果。有什么想法吗?

4 个答案:

答案 0 :(得分:0)

如果你想检查一个值是否为空或者是' 0'你可以做到以下几点:

if nvl(rev.revenue_in,'0')='0'
then

nvl()函数将使用第二个参数中指定的值替换null值。

所以你的最后一个解决方案应该可行。

case
    when nvl(rev.revenue_in, '0') = '0'
    or nvl(rev.revenue_out, '0') = '0'
    then tur.turnover_out
end "Revenue out"

你的案例陈述中没有其他内容,那么如果两个值都不是' 0'那么应该返回什么?

答案 1 :(得分:0)

按照您需要的方式使用以下内容。在参数中不会评估NULL。

case
    when (rev.revenue_in is null or rev.revenue ='0'
    or rev.revenue_out is null  or rev.revenue_out ='0')
    then tur.turnover_in
end "Revenue in",

答案 2 :(得分:0)

这是一个概念验证' 提供的解决方案与您在示例中描述的内容完全相同:只需复制粘贴并运行

select 
case
    when nvl(revenue_in, '0') = '0'
    or nvl(revenue_out, '0') = '0'
    then turnover_in
end "Revenue in",
case
    when nvl(revenue_in, '0') = '0'
    or nvl(revenue_out, '0') = '0'
    then turnover_out
end "Revenue out",
Turnover_in , Turnover_out 
from (select  null as Revenue_in,0 as Revenue_out,1000 as Turnover_in,1500 Turnover_out from dual) rev 

答案 3 :(得分:0)

好的......指的是原始帖子和目前提供的解决方案。 (我还没有读过所有内容,所以请原谅我已经说过了。)

...IN (NULL, ...)

不起作用,因为...x IN (1, 2, 3)表示x = 1 OR x = 2 OR x = 3(尽管查询优化器会将IN重写为连接,但逻辑含义相同)。但是在Oracle和SQL标准中,NULL = NULL不是TRUE;它是未知的。实际上,两个未定义的值可能相等也可能不相等,即使它们都被称为NULL。因此,IN通常无法检查NULL

然后,NVL(或coalesce)的解决方案可能有效,这是一种正确的方法。我个人更愿意完全写出意图; Raj_Te的解决方案就是这样。 NVL的解决方案往往会掩盖您的逻辑和意图,并且将来可能更难为其他开发人员维护和调试。文档可以提供帮助,但最好是编写"自我记录"代码。

正如其他人所注意到的那样,case语句到处都缺少else子句,因此当它们不为null或0时,不返回revenue_inrevenue_out个值,查询将在这些列中返回NULL。

我也发现要求不清楚......应该" IN"和" OUT"列要单独处理?这不是OP所尝试的。我提供了解决问题的解决方案,对我来说是有意义的;如果我的解释(已经与他/她的明显不同)不正确,OP可以自由修改。

select case when rev.revenue_in  is null or rev.revenue_in  = 0 then tur.turnover_in 
                               else rev.revenue_in  end as revenue_in,
       case when rev.revenue_out is null or rev.revenue_out = 0 then tur.turnover_out
                               else rev.revenue_out end as revenue_out