2016-09-29 16 views
0

我有一個表格,其中包含客戶端代碼,開始日期,結束日期和客戶端在開始和結束日期之間的表現。我現在想要將這些性能數字重新設置爲100,以便在SSRS圖表中報告它們。在Excel中很容易做到這一點,但我不想在表格上創建另一個字段,並用各自的基於重新值的值更新所有行。我已經編寫了以下代碼塊來運行SSRS報告數據集,並且我在執行它時得到'沒有數據'。但是我需要爲我選擇的客戶重新創建13行。另外我需要以查詢格式輸出(如下所示),因爲輸出是用於SSRS圖表的。謝謝。使用while循環執行select查詢以獲取所有行值和計算列

DECLARE 
    i FLOAT(126) :=100; 
    rowno number :=1; 
    n NUMBER; 
    clicode VARCHAR(10); 
    startdate DATE; 
    enddate DATE; 
    performance FLOAT(126); 
    month VARCHAR(10); 
    year VARCHAR(10); 
    rebased_perf FLOAT(126);   
    BEGIN 
    select count(*) into n from performance;    
    WHILE rowno <= n LOOP 
    select a.*,i*(1+(a.performance/100)) as rebased_perf into rowno,clicode,startdate,enddate,performance,month,year,rebased_perf from 
    (select rownum ,b.* from 
    (select clicode,startdate,enddate,performance,month,year from performance 
    where period='Halfyearly' 
    and clicode='XXX004' 
    order by enddate) b)a 
    where rownum=rowno; 
    i:=rebased_perf; 
    rowno:=rowno+1; 
    END LOOP; 
    END; 

CLICODE  STARTDATE ENDDATE  PERFORMANCE REBASED_PERF 
Startbase  05-Oct-09        100 
XXX004  05-Oct-09 05-Apr-10 3.85   103.85 
XXX004  05-Apr-10 05-Oct-10 0.63   104.50 
XXX004  05-Oct-10 05-Apr-11 4.58   109.29 
XXX004  05-Apr-11 05-Oct-11 -8.07  100.47 
XXX004  05-Oct-11 05-Apr-12 8.13   108.63 
+1

該代碼可以使用某些格式(縮進)! –

+0

這是我第一次嘗試使用循環,我確定它需要很多格式化 – danny

+0

您是否必須爲此使用循環(或更普遍的PL/SQL)?它是你學習PL/SQL,循環,遊標等的一部分嗎?如果不是普通的SQL解決方案几乎肯定會更有效率。 – mathguy

回答

2

純SQL解決方案:

如果你在你的數據有一個以上的CLIcode(你可能做,否則你不會有此列) ,有一行顯示「startbase」而不是CLI代碼是沒有意義的。它是「基數」的事實可以在enddateperformance的NULL中看到,而在growth_of_100中可以看到100。另外,我假設第一行是在您的基礎數據中;它不應該是,它可以從其他行產生。根據需要調整。即使您在某個應用程序中需要輸出,仍然最好運行普通SQL查詢並僅將其輸出導入到應用程序中。

with 
    test_data (clicode, startdate, enddate, performance) as (
     select 'XXX004', date '2009-10-05', null    , null from dual union all 
     select 'XXX004', date '2009-10-05', date '2010-04-05', 3.85 from dual union all 
     select 'XXX004', date '2010-04-05', date '2010-10-05', 0.63 from dual union all 
     select 'XXX004', date '2010-10-05', date '2011-04-05', 4.58 from dual union all 
     select 'XXX004', date '2011-04-05', date '2011-10-05', -8.07 from dual union all 
     select 'XXX004', date '2011-10-05', date '2012-04-05', 8.13 from dual 
    ) 
-- 
-- end of test data; actual query begins here 
select clicode, startdate, enddate, performance, 
     round(100 * exp(sum(ln(1 + nvl(performance,0)/100)) over 
      (partition by clicode order by enddate asc nulls first)), 2) as growth_of_100 
from test_data 
order by clicode, enddate asc nulls first 
; 


CLICODE STARTDATE ENDDATE PERFORMANCE GROWTH_OF_100 
------- --------- --------- ----------- ------------- 
XXX004 05-Oct-09        100.00 
XXX004 05-Oct-09 05-Apr-10  3.85  103.85 
XXX004 05-Apr-10 05-Oct-10  0.63  104.50 
XXX004 05-Oct-10 05-Apr-11  4.58  109.29 
XXX004 05-Apr-11 05-Oct-11  -8.07  100.47 
XXX004 05-Oct-11 05-Apr-12  8.13  108.64 

6 rows selected. 
+0

感謝你,不知道我可以只使用SQL來做這件事,在另一個說明中,我添加了start-base,只是爲了使計算清楚。 – danny

0

你不能按照你想要的方式使用rownum。你還是使用遊標或直接隱含的循環:

DECLARE 
    i FLOAT(126) :=100; 
    rebased_perf FLOAT(126);   
BEGIN 
    for x in (
    select a.*,i*(1+(a.performance/100)) as rebased_perf from (
       select clicode,startdate,enddate,performance,month,year from performance 
       where period='Halfyearly' and clicode='XXX004') a 
      order by enddate 
) loop 
    -- no more "into" rowno,clicode,startdate,enddate,performance,month,year,rebased_perf 
    --- but you can address the fields with "x.<field>" 
    i:=x.rebased_perf; 
    dbms_output.put_line('i='||i); 
    END LOOP; 
END; 
+0

我不得不使用rownum,因爲必須按照特定的順序(在我的情況下從09年10月到16月)完成重新組合,如果順序混合起來,我可能會得到錯誤的表演。另外我怎樣才能得到上述查詢格式的結果。謝謝。 – danny

+0

@danny,你應該嘗試在A表之外的'endate'(我編輯了我的答案);你應該問另一個問題。並顯示你的嘗試。我們不會爲你做所有的工作。你在這裏學習,不是嗎? –