簡體   English   中英

在Oracle SQL中循環,將一個月與另一個月進行比較

[英]Loop in Oracle SQL, comparing one month to another

我必須草擬一個執行以下操作的SQL查詢:

將當前周(例如第10周)的金額與前4周(周#9,8,7,6)的平均金額進行比較。

現在,我需要每月運行一次查詢,所以要說幾周(10,11,12,13)。 到目前為止,我已經運行了四次,每次運行都給出了周參數。

例如我當前的查詢是這樣的:

select account_id, curr.amount,hist.AVG_Amt
from 
(
    select 
        to_char(run_date,'IW') Week_ID,
        sum(amount) Amount,
        account_id
    from Transaction t
    where to_char(run_date,'IW') = '10'
    group by account_id,to_char(run_date,'IW')
) curr,
(
    select account_id,
        sum(amount) / count(to_char(run_date,'IW')) as AVG_Amt
    from Transactions 
    where to_char(run_date,'IW') in ('6','7','8','9')
    group by account_id
) hist
where 
    hist.account_id = curr.account_id
    and curr.amount > 2*hist.AVG_Amt;

如您所見,如果我必須在第11、12、13周運行上述查詢,則必須分別運行3次。 有沒有一種方法可以合並或構造查詢,使我只運行一次就可以得到比較數據呢?

只是一個附加信息,我需要將數據導出到Excel(在PL / SQL開發人員上運行查詢后執行此操作)並導出到Excel。

謝謝!

-阿比

您可以使用相關子查詢來獲取給定一周內最近4周的金額總和。

select 
    to_char(run_date,'IW') Week_ID,
    sum(amount) curAmount,
    (select sum(amount)/4.0 from transaction 
     where account_id = t.account_id
     and to_char(run_date,'IW') between to_char(t.run_date,'IW')-4 
                                        and to_char(t.run_date,'IW')-1
    ) hist_amount,
    account_id
from Transaction t
where to_char(run_date,'IW') in ('10','11','12','13')
group by account_id,to_char(run_date,'IW')

編輯:基於OP對以上查詢性能的評論,也可以使用lag來獲取前一行的值來完成此操作。 可以使用case表達式來統計最近4周內存在的記錄數。

with sum_amounts as 
(select to_char(run_date,'IW') wk, sum(amount) amount, account_id 
 from Transaction
 group by account_id, to_char(run_date,'IW')
)
select wk, account_id, amount, 
1.0 * (lag(amount,1,0) over (order by wk) + lag(amount,2,0) over (order by wk) +
       lag(amount,3,0) over (order by wk) + lag(amount,4,0) over (order by wk)) 
/ case when lag(amount,1,0) over (order by wk) <> 0 then 1 else 0 end +
  case when lag(amount,2,0) over (order by wk) <> 0 then 1 else 0 end +
  case when lag(amount,3,0) over (order by wk) <> 0 then 1 else 0 end +
  case when lag(amount,4,0) over (order by wk) <> 0 then 1 else 0 end 
as hist_avg_amount 
from sum_amounts

我認為這就是您要尋找的:

with lagt as (select to_char(run_date,'IW') Week_ID, sum(amount) Amount, account_id 
  from Transaction t 
  group by account_id, to_char(run_date,'IW'))
select Week_ID, account_id, amount, 
  (lag(amount,1,0) over (order by week) + lag(amount,2,0) over (order by week) +
   lag(amount,3,0) over (order by week) + lag(amount,4,0) over (order by week)) / 4 as average 
  from lagt;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM