2016-11-15 3 views
1

クエリに問題があり、複数のビューと完全な手順になり、 の順番で分散を表示するテーブルが生成されます。 正直なところ、SQL Serverでは、これを1つのクエリで実行できます。 しかし、Oracle 11gの場合、同じことを実行するのが難しく、クエリーをオフにするのは難しいです。 遅く実行してください。私のクエリを実行するのに5分以上かかってしまいました。それは問題ありません。号日付間の実行中のパーセント差の合計を取得する

私はデータのテーブル

DATE  SERVICE  ENV  RESPONSES 
15-NOV-2016  PROD  T1  4793 
15-NOV-2016  PROD  U1  3245 
15-NOV-2016  PROD  X1  4984 
14-NOV-2016  PROD  T1  5812 
14-NOV-2016  PROD  U1  3918 
14-NOV-2016  PROD  X1  3282 
13-NOV-2016  PROD  T1  11231 
13-NOV-2016  PROD  U1  1564 
13-NOV-2016  PROD  X1  2816 

注意があります。このデータは数年さかのぼる、およびレポートのために6つの環境

をカバーして、私はこのようになります結果セットを生成する必要がある、

を+/- 10%よりも大きい差異がある場合
DATE  ENV T1  U1 X1 TOTAL VARIANCE 
20161115 PROD 4793 3245 4984 14022 +7.76% 
20161114 PROD 5812 3918 3282 13012 -16.65% 
20161113 PROD 11231 1564 2816 15611 +9.13% 

このレポートでは、出て行く

さらに、ビュー全体ではなく、3〜5行だけを送信したい。 パーティショニングを使用しようとしましたが、クエリが遅くなり、必要なデータが生成されませんでした。

デザインには現在、メインテーブルに参加してデータをピボットするための6つの別々のビューが作成されています しかし、分散を生成するためにクエリを取得することはできません。 分散は次のように計算される((現在の日付の合計/昨日の合計) - 1)* 100 または((15611分の13012) - 1.00)×100 = -16.65

各ビュー

CREATE OR REPLACE FORCE VIEW USAGE_T1 
(
    DATEREF, 
    REALM, 
    TOTAL 
) 
AS 
    SELECT DATE, ENV, TOTAL 
    FROM USAGE_COUNT 
    WHERE ENV = 'T1'; 

このクエリはテーブルを作成しますが、分散がありません

SELECT 
    TO_CHAR(base.ENDDATE, 'YYYYMMDD') AS DATEREF 
    , base.ENV 
    , T1.TOTAL AS "T1" 
    , U1.TOTAL AS "U1" 
    , X1.TOTAL AS "X1" 
    , NVL(T1.TOTAL, 0) + NVL(U1.TOTAL,0) + NVL(X1.TOTAL,0) AS "TOTAL" 
FROM USAGE base 
LEFT JOIN USAGE_T1 T1 
    ON T1.DATEREF = TO_CHAR(base.ENDDATE, 'YYYYMMDD') 
LEFT JOIN USAGE_U1 U1 
    ON U1.DATEREF = TO_CHAR(base.ENDDATE, 'YYYYMMDD') 
LEFT JOIN USAGE_X1 X1 
    ON X1.DATEREF = TO_CHAR(base.ENDDATE, 'YYYYMMDD') 
WHERE base.ENV = 'PROD' 
GROUP BY base.ENV, base.ENDDATE, T1.TOTAL, U1.TOTAL, X1.TOTAL 
ORDER BY base.ENDDATE DESC; 

ご協力いただきありがとうございます。

はあなたが必要なものです

答えて

1

は、私が思うありがとう:ここ

with t (dat, env, service, responses) as (
select to_date('15-NOV-2016', 'dd-mon-yyyy'),  'PROD',  'T1',  '4793' from dual union all 
select to_date('15-NOV-2016', 'dd-mon-yyyy'),  'PROD',  'U1',  '3245' from dual union all 
select to_date('15-NOV-2016', 'dd-mon-yyyy'),  'PROD',  'X1',  '4984' from dual union all 
select to_date('14-NOV-2016', 'dd-mon-yyyy'),  'PROD',  'T1',  '5812' from dual union all 
select to_date('14-NOV-2016', 'dd-mon-yyyy'),  'PROD',  'U1',  '3918' from dual union all 
select to_date('14-NOV-2016', 'dd-mon-yyyy'),  'PROD',  'X1',  '3282' from dual union all 
select to_date('13-NOV-2016', 'dd-mon-yyyy'),  'PROD',  'T1',  '11231' from dual union all 
select to_date('13-NOV-2016', 'dd-mon-yyyy'),  'PROD',  'U1',  '1564' from dual union all 
select to_date('13-NOV-2016', 'dd-mon-yyyy'),  'PROD',  'X1',  '2816' from dual) 
select tt.*, (total/lag(total, 1, null) over (order by dat) - 1) * 100 variance 
    from (select to_char(dat, 'yyyymmdd') dat, t1, x1, u1, t1 + x1 + u1 total 
      from t 
     pivot (sum(responses) for service in ('T1' t1, 'X1' x1, 'U1' u1)) 
     ) tt; 

with t建設 - ソースデータは、内部クエリ - ピボットを別のサービスのための1つの行のデータに入れて、その後で外部クエリ関数lagは前の行の値を計算します。詳細については、lag functionおよびpivot queryのドキュメントを参照してください。

更新
方法lag作品:lagは、前の行の値をとります。最初の引数は、取るべきデータを持つカラムの名前、現在の行の2番目のカウント(前に1を取り、前に2 - 2行など)、前の行がない場合は3番目のデフォルト値です。行の順序は、注文句(上記のorder by dat)によって定義されます。データシフトの方向を変更するには、次の行の戻り値(lagとほとんど同じ)の使用関数leadのソート順(asc/desc)を変更します。

+0

それは90%働いた。ありがとう、それは大幅に私のクエリを簡素化し、物事を少しきれいにしました。2つの問題は、分散が必要なものの逆数であり、もう1つは分散値が間違った行に現れていることです。最初の問題は、ラッピング(1 /(合計/ 1、ヌル)over(order by dat) - 1)* 100でラップして解決しましたが、もう1つは私を困らせました。行? –

+0

@AllanL更新された回答 – Dmitry

+0

ありがとうございました!私はLAGを読んで、すべてをうまく調整したLEADを見つけました。本当に迅速で非常に有益な応答に感謝します。 –

関連する問題