Oracle Divisor等于零

时间:2013-04-03 21:56:01

标签: sql oracle

如何围绕此查询包装DECODE以处理零除数而不计算分母求和两次?除了thedate和舍入百分比之外,我不想返回任何其他内容。

SELECT thedate, ROUND (100*
  SUM( case when TRUNC(ACTIVITY_END_DATE) <= thedate
     AND TRUNC(ACTIVITY_END_DATE) >= add_months( trunc(thedate,'mm'), -12) 
     AND trunc(ACTIVITY_END_DATE) <= trunc(ACTIVITY_NEED_DATE) 
     AND SYSDATE  >=  trunc(thedate,'mm') then 1 else 0 end )  
  /
  SUM( case when TRUNC(ACTIVITY_END_DATE) <= thedate 
     AND TRUNC(ACTIVITY_END_DATE) >= add_months( trunc(thedate,'mm'), -12) 
     AND SYSDATE  >=  trunc(thedate,'mm') then 1 else 0 end ) ) as OTR12 
       FROM TEST
       cross join (  select add_months(last_day(SYSDATE), level-7) as thedate 
       from dual connect by level <= 12  )  
       GROUP BY thedate 
       ORDER BY thedate 

似乎在DECODE中,我必须两次进行分母求和 DECODE(denominator_summation,0,NULL, numerator_summation / denominator_summation)

3 个答案:

答案 0 :(得分:1)

使用having子句:

having 
SUM( case when TRUNC(ACTIVITY_END_DATE) <= thedate 
 AND TRUNC(ACTIVITY_END_DATE) >= add_months( trunc(thedate,'mm'), -12) 
 AND SYSDATE  >=  trunc(thedate,'mm') then 1 else 0 end ) ) as OTR12 
   FROM TEST
   cross join (  select add_months(last_day(SYSDATE), level-7) as thedate 
   from dual connect by level <= 12  )
> 0

答案 1 :(得分:1)

SELECT 
  thedate, 
  ROUND (
    100 * SUM( 
       case when TRUNC(ACTIVITY_END_DATE) <= thedate
       AND TRUNC(ACTIVITY_END_DATE) >= add_months( trunc(thedate,'mm'), -12) 
       AND trunc(ACTIVITY_END_DATE) <= trunc(ACTIVITY_NEED_DATE) 
       AND SYSDATE  >=  trunc(thedate,'mm') then 1 else 0 end 
    ) / nullif(SUM( 
       case when TRUNC(ACTIVITY_END_DATE) <= thedate 
       AND TRUNC(ACTIVITY_END_DATE) >= add_months( trunc(thedate,'mm'), -12) 
       AND SYSDATE  >=  trunc(thedate,'mm') then 1 else 0 end 
    ), 0) 
  ) as OTR12 
FROM 
  TEST
  cross join (  
     select add_months(last_day(SYSDATE), level-7) as thedate 
     from dual connect by level <= 12  
  )  
GROUP BY thedate 
ORDER BY thedate 

答案 2 :(得分:0)

如何使用子查询?

select thedate, (case when denom <> 0 then round(100*num/denom) end)
from (SELECT thedate,
             SUM( case when TRUNC(ACTIVITY_END_DATE) <= thedate
                            AND TRUNC(ACTIVITY_END_DATE) >= add_months( trunc(thedate,'mm'), -12) 
                            AND trunc(ACTIVITY_END_DATE) <= trunc(ACTIVITY_NEED_DATE) 
                            AND SYSDATE  >=  trunc(thedate,'mm') then 1 else 0
                  end )   as num,
             SUM( case when TRUNC(ACTIVITY_END_DATE) <= thedate 
                        AND TRUNC(ACTIVITY_END_DATE) >= add_months( trunc(thedate,'mm'), -12) 
                        AND SYSDATE  >=  trunc(thedate,'mm') then 1 else 0 end ) ) as OTR12 
        FROM TEST cross join
             (  select add_months(last_day(SYSDATE), level-7) as thedate 
                from dual connect by level <= 12  )  
        GROUP BY thedate 
     ) t
order by thedate