[英]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.