Desculpas pelo título ruim, eu não tinha certeza do que seria um bom título para isso.
Atualmente, esses são (visão simplificada dos) dados com os quais estou trabalhando
Agent | Commission
---------|------------
Smith | 100
Neo | 200
Morpheus | 300
Preciso calcular a porcentagem da comissão total pela qual cada agente é responsável.
Portanto, para o agente Smith, a porcentagem seria calculada como (Agent Smith's commission / Sum(commission)*100
Então, meus dados esperados seriam
Agent | Commission | % Commission
---------|---------------|---------------
Smith | 100 | 17
Neo | 200 | 33
Morpheus | 300 | 50
Eu tenho uma função retornando a comissão para cada agente. Eu tenho outra função retornando a porcentagem como (Commission/Sum(Commission))*100
. O problema é que Sum(commission)
é calculado para cada linha e, como essa consulta seria executada em um Data Warehouse, o conjunto de dados seria bastante grande (atualmente, tem pouco menos de 2000 registros) e, honestamente, uma abordagem ruim (IMO )
Existe uma maneira de Sum(Commission)
não calcular para cada linha que está sendo buscada?
Eu estava pensando em algo nas linhas de uma consulta de 2 partes, a primeira parte buscaria a sum(commission)
variável / tipo de pacote e a segunda parte se referiria a esse valor pré-calculado, mas não tenho certeza de como conseguir isso.
Estou limitado a usar SQL e estou executando no Oracle 10g R2.
fonte
Respostas:
Você está procurando o
analytical function
ratio_to_reportfonte
Para retornar todos os agentes com suas comissões e porcentagens de comissão, use uma função analítica sem cláusula analítica para que a partição esteja sobre a tabela inteira:
Como aprendi com René Nyffenegger (+1), a função ratio_to_report aperta essa sintaxe.
O uso de um pacote para armazenar o SUM da Comissão envolveria PL / SQL, que você excluiu especificamente ao indicar que deseja uma solução SQL, mas como você já está usando funções, presumo que sua intenção não foi excluir PL / SQL. Se for esse o caso, a solução do pacote pode ajudar, mas depende de como seu aplicativo funciona.
Quando sua sessão é criada e chama a função no pacote para obter a comissão, há uma chamada implícita ao construtor de pacotes que pode obter a soma e armazená-la. Em seguida, você pode fazer referência à soma armazenada em sua função de comissão de comissão e ela só precisará fazer a soma uma vez. Obviamente, assim que você chamar a função de uma sessão diferente, a soma será calculada novamente. Além disso, chamar a função para cada agente seria consideravelmente menos eficiente do que chamar uma instrução SQL para todos os agentes se seu aplicativo puder ser projetado dessa maneira.
Você pode considerar transformar sua função em um procedimento que retorne um cursor para a consulta acima ou talvez tenha uma função que retorne os resultados da consulta como um conjunto de resultados em pipeline.
Dados de amostra:
fonte
Você pode tentar a seguinte consulta, a soma (comissão) será calculada apenas uma vez:
fonte
fonte