it-swarm-eu.dev

Výpočet procenta řádku z celkové částky

Omlouvám se za špatný název, nebyl jsem si jistý, jaký by to byl dobrý název.

Toto jsou v současné době (zjednodušené zobrazení) data, se kterými pracuji

Agent    |  Commission     
---------|------------
Smith    |    100
Neo      |    200
Morpheus |    300

Musím vypočítat procento z celkové provize, za kterou odpovídá každý agent.

Pro agenta Smithe by tedy bylo procento vypočteno jako (Agent Smith's commission / Sum(commission)*100

Takže moje očekávané údaje budou

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

Mám funkci vracející provizi pro každého agenta. Mám jinou funkci, která vrací procento jako (Commission/Sum(Commission))*100. Problém je v tom, že Sum(commission) se vypočítá pro každý řádek a vzhledem k tomu, že tento dotaz bude spuštěn v datovém skladu, bude sada dat poměrně velká (v současné době je to méně než 2000 záznamů) a docela upřímně, špatný přístup (IMO).

Existuje způsob, jak nechat vypočítat funkci Sum(Commission) pro každý řádek, který je vyvolán?

Přemýšlel jsem o něčem na řádcích dvojdílného dotazu, první část by načítala sum(commission) do proměnné/typu balíčku a druhá část by odkazovala na tuto předem vypočítanou hodnotu, ale nejsem určitě, jak toho mohu dosáhnout.

Jsem omezen na používání SQL a používám Oracle 10g R2.

13
Sathyajith Bhat

Hledáte analytical functionratio_to_report

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

Chcete-li vrátit všem agentům jejich provize a procenta provizí, použijte analytická funkce bez analytické klauze, takže oddíl je nad celou tabulkou:

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

Jak jsem se dozvěděl od René Nyffenegger (+1), funkce ratio_to_report tuto syntaxi zpřísňuje.

Použití balíčku k uložení provize SUM by zahrnovalo PL/SQL, které jste výslovně vyloučili uvedením toho, že chcete řešení SQL, ale protože již používáte funkce, předpokládám, že vaším záměrem nebylo vyloučit PL/SQL. Pokud tomu tak je, pak může pomoci řešení balíčku, ale záleží to na tom, jak vaše aplikace funguje.

Když je vaše relace poprvé vytvořena a volá funkci v balíčku, aby získala provizi, dojde k implicitnímu volání konstruktoru balíčků, které by mohlo získat částku a uložit ji. Pak můžete odkazovat na uloženou částku ve vaší funkci provize provize a bude muset tuto částku provést pouze jednou. Jakmile zavoláte funkci z jiné relace, suma se samozřejmě vypočítá znovu. Volání funkce pro každého agenta by také bylo mnohem méně efektivní než volání jednoho příkazu SQL pro všechny agenty, pokud by vaše aplikace mohla být navržena tímto způsobem.

Možná budete chtít zvážit proměnu vaší funkce v proceduru, která vrací kurzor pro výše uvedený dotaz, nebo může mít funkci, která vrací výsledky dotazu jako pipelinovanou sadu výsledků.

Vzorek dat:

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

Můžete zkusit následující dotaz, suma (provize) bude vypočítána pouze jednou:

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