Disculpas por el mal título, no estaba seguro de cuál sería un buen título para esto.
Esta es actualmente (vista simplificada de) los datos con los que estoy trabajando
Agent | Commission
---------|------------
Smith | 100
Neo | 200
Morpheus | 300
Necesito calcular el porcentaje de la comisión total, cada agente es responsable.
Entonces, para el Agente Smith, el Porcentaje se calcularía como (Agent Smith's commission / Sum(commission)*100
Entonces, mis datos esperados serían
Agent | Commission | % Commission
---------|---------------|---------------
Smith | 100 | 17
Neo | 200 | 33
Morpheus | 300 | 50
Tengo una función que devuelve la comisión para cada agente. Tengo otra función que devuelve el porcentaje como (Commission/Sum(Commission))*100
. El problema es que Sum(commission)
se calcula para todas y cada una de las filas, y dado que esta consulta se ejecutaría en un Data Warehouse, el conjunto de datos sería bastante grande (actualmente, está por debajo de 2000 registros) y, sinceramente, un mal enfoque (IMO )
¿Hay alguna manera de que Sum(Commission)
no se calcule para cada fila que se va a buscar?
Estaba pensando algo en las líneas de una consulta de 2 partes, la primera parte buscaría la sum(commission)
variable / tipo de paquete y la segunda parte se referiría a este valor precalculado, pero no estoy seguro de cómo puedo lograr esto.
Estoy limitado a usar SQL y estoy ejecutando Oracle 10g R2.
fuente
Respuestas:
Estás buscando el
analytical function
ratio_to_reportfuente
Para devolver todos los agentes con sus comisiones y porcentajes de comisión, use una función analítica sin cláusula analítica para que la partición esté sobre toda la tabla:
Como aprendí de René Nyffenegger (+1), la función ratio_to_report refuerza esta sintaxis.
El uso de un paquete para almacenar la SUMA de la Comisión implicaría PL / SQL, que excluyó específicamente al indicar que desea una solución SQL, pero dado que ya está utilizando funciones, supongo que su intención no era excluir PL / SQL. Si este es el caso, la solución del paquete puede ayudar, pero depende de cómo funcione su aplicación.
Cuando su sesión se crea por primera vez y llama a la función en el paquete para obtener la comisión, hay una llamada implícita al constructor de paquetes que podría obtener la suma y almacenarla. Luego, podría hacer referencia a la suma almacenada en su función de obtener comisión y solo tendría que hacer la suma una vez. Por supuesto, tan pronto como llame a la función desde una sesión diferente, la suma se calculará nuevamente. Además, llamar a la función para cada agente sería considerablemente menos eficiente que llamar a una declaración SQL para todos los agentes si su aplicación se puede diseñar de esa manera.
Es posible que desee considerar convertir su función en un procedimiento que devuelva un cursor para la consulta anterior o tal vez tenga una función que devuelva los resultados de la consulta como un conjunto de resultados canalizados.
Data de muestra:
fuente
Puede intentar la siguiente consulta, la suma (comisión) solo se calculará una vez:
fuente
fuente