2011-01-19 33 views
10

Tengo una tabla en Oracle con múltiples filas por una parte determinada. Cada fila tiene una cantidad y un precio asociado a ella. También hay una cantidad total a la que se suma el conjunto de filas para una determinada parte. A continuación hay una muestra de los datos. Lo que necesito es obtener el precio promedio ponderado de la pieza. Por ejemplo, si una cantidad de 100 de una parte tiene un precio de 1 y una cantidad de 50 tiene un precio de 2 el precio medio ponderado es 1.33333333Consulta para encontrar un precio promedio ponderado

PART TOTAL_QTY QTY PRICE_PER 
---------------------------------- 
part1 317  244 27 
part1 317  40 53.85 
part1 317  33 24.15 

Ideas?

Respuesta

16

Prueba esto:

SELECT part, SUM(qty*price_per)/SUM(qty) 
    FROM <YOUR_TABLE> 
GROUP BY part 
+0

Supongo que no es necesario el campo TOTAL_QTY más. Viola descaradamente el principio de datos de unicidad: cada dato debe aparecer solo una vez. – Josep

0

crear una función de agregado definida por el usuario para calcular el promedio ponderado:

CREATE OR REPLACE TYPE WEIGHTED_AVG_O AS OBJECT ( 
    sum_of_weights NUMBER, 
    sum_of_weights_times_value NUMBER, 

    STATIC FUNCTION ODCIAGGREGATEINITIALIZE(cs_ctx IN OUT WEIGHTED_AVG_O) RETURN NUMBER, 
    MEMBER FUNCTION ODCIAGGREGATEITERATE (self IN OUT WEIGHTED_AVG_O, value IN WEIGHTED_AVG_O) RETURN NUMBER, 
    MEMBER FUNCTION ODCIAGGREGATEMERGE  (self IN OUT WEIGHTED_AVG_O, ctx2 IN OUT WEIGHTED_AVG_O) RETURN NUMBER, 
    MEMBER FUNCTION ODCIAGGREGATETERMINATE (self IN OUT WEIGHTED_AVG_O, returnvalue OUT NUMBER, flags IN NUMBER) RETURN NUMBER 
); 
/



CREATE OR REPLACE TYPE BODY WEIGHTED_AVG_O 
AS 

    STATIC FUNCTION ODCIAGGREGATEINITIALIZE(cs_ctx IN OUT WEIGHTED_AVG_O) RETURN NUMBER 
    IS 
    BEGIN 
    cs_ctx := WEIGHTED_AVG_O(0, 0); 
    RETURN odciconst.success; 
    END; 

    MEMBER FUNCTION ODCIAGGREGATEITERATE (self IN OUT WEIGHTED_AVG_O, value IN WEIGHTED_AVG_O) RETURN NUMBER 
    IS 
    BEGIN 
    self.sum_of_weights := self.sum_of_weights + value.sum_of_weights; 
    self.sum_of_weights_times_value := self.sum_of_weights_times_value + value.sum_of_weights * value.sum_of_weights_times_value; 
    RETURN odciconst.success; 
    END; 

    MEMBER FUNCTION ODCIAGGREGATEMERGE  (self IN OUT WEIGHTED_AVG_O, ctx2 IN OUT WEIGHTED_AVG_O) RETURN NUMBER 
    IS 
    BEGIN 
    RETURN odciconst.success; 
    END; 

    MEMBER FUNCTION ODCIAGGREGATETERMINATE (self IN OUT WEIGHTED_AVG_O, returnvalue OUT NUMBER, flags IN NUMBER) RETURN NUMBER 
    IS 
    BEGIN  
    IF sum_of_weights = 0 THEN 
     returnvalue := NULL; 
    ELSE 
     returnvalue := sum_of_weights_times_value/sum_of_weights; 
    END IF; 
    RETURN odciconst.success; 
    END; 

END; 
/


CREATE OR REPLACE FUNCTION WEIGHTED_AVG (input WEIGHTED_AVG_O) 
    RETURN NUMBER PARALLEL_ENABLE 
    AGGREGATE USING WEIGHTED_AVG_O; 
/

consulta con sus datos:

SELECT part, WEIGHTED_AVG(WEIGHTED_AVG_O(qty, price_per)) 
    FROM <YOUR_TABLE> 
GROUP BY part; 
Cuestiones relacionadas