2013-04-03 96 views
0

如何在此查詢的周圍包裝DECODE以處理零除數而不計算分母總和兩次?我不想返回thedate以外的任何值和四捨五入的百分比。Oracle除數等於零

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(denominator_summation,0,NULL, numerator_summation/denominator_summation)

回答

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 
+0

子查詢工作,我接受它作爲答案。我只注意到第三個答案。看起來他們都工作。 – jeff 2013-04-03 22:34:34

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 
+0

我在這裏看到的兩個問題:(1)它將排除輸出的一部分,而不是僅僅示出了默認列值的; (2)你不需要重複這個部分**兩次**(在身體中,再次在HAVING中)? – 2013-04-03 22:04:00

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 
+0

+1爲您的答案。 Gordon在SQLplus中工作,所以我在看到並嘗試過你之前就接受了它。然而,我最終使用你的,因爲我正在Java應用程序中使用Hibernate實現查詢。 Hibernate將Gordon作爲一個字符串數組返回,這是一個BigDecimals數組,這正是我需要的。 http://weblogs.java.net/blog/mb124283/archive/2007/04/java_persistenc.html – jeff 2013-04-03 23:01:35