2016-04-29 2 views
0

現在の月と前の月の間の2つの値の変化を計算しようとしています。 いろいろな月に合計通話があり、前月の通話との差が月ごとに異なるとします。 Uは、表は、ベンダー、月が含まれており、前月アマゾンの赤方偏移データベースの値の変化を計算する

select vendor, 
     nvl(round(sum(calls),0),0.00) as "total_calls", 
     nvl((((lag(CAST(sum(calls) AS decimal) ,0) over(order by month)) -    
       (lag(CAST(sum(calls) AS DECIMAL),1) over(order by month)))/
       (lag(CAST(sum(calls) AS DECIMAL),1) over(order by month))), 0) as tot_calls_variation 
    from table_summary 
group by full_month,vendor 
order by month,vendor 

遅れでデータがない場合には(私はそれが同じベンダーの間違った結果を与える次のクエリナットを試してみました 各月に呼び出す必要があり)関数は与えられたindex.butで行を返します。しかし、バラツキは行ごとに計算されるので、間違った結果になります 他の方法があるのでしょうか?おかげ

+0

ベンダーでWINDOW機能を使用するオプションをチェックしましたか? – Guy

答えて

0

は、それはあなたのデータおよび望ましい結果を見ずに言うのは難しいですが、おそらくあなただけの自己と一緒に行くのより良いは、ウィンドウ関数の代わりに加入されることがあります。

SELECT 
    month_summary.vendor, 
    month_summary.calls, 
    month_summary.calls - prev_month_summary.calls/prev_month_summary.calls) as tot_calls_variation 
FROM 
    (SELECT vendor, full_month, sum(calls) as calls FROM table_summary GROUP BY vendor, full_month) as month_summary 
    INNER JOIN (SELECT vendor, full_month, sum(calls) as calls FROM table_summary GROUP BY vendor, full_month) as prev_month_summary ON 
     month_summary.vendor = prev_month_summary.vendor AND 
     month_summary.full_month - 1 = prev_month_summar.full_month 
0

グループ化とラグとの主な問題/リード関数はグループ間の遷移点です。

あなたは、このようなデータを持っている想像して、あなたは、カラムAによってグループ化すると、列Bの順序に基づいてCの値に操作を実行します。

A  B  C 
=== === === 
Y  2015 1 
Y  2016 2 
Z  2015 3 
Z  2016 4 

あなたはラグ関数を使用します

A  B  C Lag(A) Lag(B) Lag(C) 
=== === === ====== ====== ====== 
Y  2015 1 null null null 
Y  2016 2 Y  2015 1 
Z  2015 3 Y  2016 2 <-- This is the record causing your problem. 
Z  2016 4 Z  2015 3 

あなたは、一般的にやりたいことは、あなたがすることによってグループ化しているすべてのフィールドを含め、あなたからあなたがそれらを除外するために、それらの上でラグ機能を使用している:あなたは、潜在的に間違った列を見ていますラグ関数が列の値と一致しない限り、計算します。

つまり、上記の例では、3番目のレコードが問題である理由は、A!= Lag(A)です。したがって、クエリにWHERE A = Lag(A)を追加すると、そのようなレコードが除外されます。

0

私はこの問題に対するWelbogの評価:ベンダー間の移行に同意します。

しかし、最も簡単な解決策は、LAG機能でPARTITION BY vendorを使用することです。 vendorの値が変更されると、これはLAGウィンドウを「閉じる」。

SELECT vendor,full_month, 
     NVL(ROUND(SUM(calls),0),0.00) as "total_calls", 
     NVL((((LAG(CAST(SUM(calls) AS DECIMAL), 0) OVER(PARTITION BY vendor ORDER BY month)) -    
      (LAG(CAST(SUM(calls) AS DECIMAL), 1) OVER(PARTITION BY vendor ORDER BY month)))/
      (LAG(CAST(SUM(calls) AS DECIMAL), 1) OVER(PARTITION BY vendor ORDER BY month))) 
      , 0) as tot_calls_variation 
    FROM table_summary 
GROUP BY vendor,full_month 
ORDER BY month,vendor 

一つの更なる事は、あなたがtable_summaryは、ベンダーが何の電話を持っていないか月間ゼロが含まれているかどうかは言及しませんでした。 でない場合、の場合、LAGは不正確な結果を生成します。

0

は、私はこのための解決策を思い付いている、私は一時テーブルを作成し、以下のよう前月ベンダーと月でそれに参加回答ありがとうございました:

select vendor,month, 
nvl(round(sum(calls),2),0.0) as "total_calls" 
into temp1 
from table_summary 
group by month,vendor 
order by month,vendor 
select tb1.month ,tb1.vendor, 
((tb1.total_calls - tb2.total_calls)/nullif(tb2.total_calls,0)) as tot_calls_variation 
from temp1 tb1 
left join temp1 tb2 on (tb1.month -1) = (tb2.month) and tb1.vendor = tb2.vendor 
order by tb1.month ; 
drop table temp1; 

これも働いていますいくつかの月にベンダーのためのデータがない場合

関連する問題