web-dev-qa-db-ja.com

合計に対する行のパーセンテージの計算

タイトルがおかしいので、申し訳ありません。これにふさわしいタイトルは何なのかわかりませんでした。

これは、現在使用している(簡略化した)データです

_Agent    |  Commission     
---------|------------
Smith    |    100
Neo      |    200
Morpheus |    300
_

各エージェントが担当する総手数料の割合を計算する必要があります。

したがって、エージェントスミスの場合、パーセンテージは_(Agent Smith's commission / Sum(commission)*100_として計算されます。

だから、私の予想データは

_Agent    |  Commission   |  % Commission    
---------|---------------|---------------
Smith    |    100        |     17
Neo      |    200        |     33
Morpheus |    300        |     50
_

エージェントごとにコミッションを返す機能があります。パーセンテージを_(Commission/Sum(Commission))*100_として返す別の関数があります。問題は、Sum(commission)が各行ごとに計算され、このクエリがデータウェアハウスで実行される場合、データセットはかなり大きくなり(現在は2000レコード未満です)、正直なところ、悪いアプローチ(IMO)。

フェッチされているすべての行についてSum(Commission)を計算しないようにする方法はありますか?

2つの部分のクエリの行で何かを考えていました。最初の部分はsum(commission)をパッケージ変数/型にフェッチし、2番目の部分はこの事前計算された値を参照しますが、私がこれをどのように達成できるかを確認してください。

SQLの使用に限定されており、Oracle 10g R2で実行しています。

13
Sathyajith Bhat

あなたはanalytical functionratio_to_reportを探しています

select 
  agent,
  round(ratio_to_report(commission) over ()*100) "% Comm."
from  
  commissions;
23

すべてのエージェントにコミッションとコミッションの割合を返すには、 analytic function を分析句なしで使用して、パーティションがテーブル全体になるようにします。

SELECT Agent, commission, 100* commission / (SUM(commission) OVER ()) "% Commission" 
FROM commissions;

RenéNyffenegger(+1)から学んだように、ratio_to_report関数はこの構文を厳しくしています。

パッケージを使用してコミッションSUMを格納する場合、SQLソリューションが必要であることを明示的に除外してPL/SQLを使用しますが、すでに関数を使用しているため、PL/SQLを除外するつもりはなかったと思います。これが当てはまる場合は、パッケージソリューションが役立つ場合がありますが、アプリケーションの動作方法によって異なります。

セッションが最初に作成され、パッケージ内の関数を呼び出してコミッションを取得すると、パッケージコンストラクターへの暗黙的な呼び出しが行われ、合計を取得して保存できます。次に、コミッション取得関数で保存された合計を参照でき、合計を1回実行するだけで済みます。もちろん、別のセッションから関数を呼び出すとすぐに、合計が再度計算されます。また、アプリケーションをそのように設計できる場合、すべてのエージェントに対して関数を呼び出すのは、すべてのエージェントに対して1つのSQLステートメントを呼び出すよりもかなり効率が悪くなります。

関数を上記のクエリのカーソルを返すプロシージャに変換することを検討するか、パイプライン化された結果セットとしてクエリの結果を返す関数を含めることができます。

サンプルデータ:

create table commissions (Agent Varchar2(100), Commission Number(3));
insert into commissions values ('Smith',100);
insert into commissions values ('Neo',200);
insert into commissions values ('Morpheus',300);
9
Leigh Riffel

次のクエリを試すことができます。sum(commission)は一度だけ計算されます。

WITH TOTAL_COMMISSION AS 
(SELECT SUM(COMMISSION) AS TOTAL FROM AGENTS)
SELECT A.AGENT_NAME, A.COMMISSION, ((A.COMMISSION/T.TOTAL)*100) AS "% COMMISSION"
FROM AGENTS A, TOTAL_COMMISSION T;
5
Robert Durgin
  select 
  Agent, Commission,
  (
      ROUND(
       (Commission *100) / 
          (
            (SELECT SUM(Commission)
             FROM commissions AS A)
          )
       ) 
  ) AS Porcentaje
  from  
  commissions
0
JoeDeg